1所需jar包
spring-tx.jar
PlatformTransactionManager接口
2 spring中基于XML的声明式事务控制配置步骤
- 配置事务管理器
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
- 配置事务通知
需要导入事务的约束
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:advice>
- 配置AOP中的通用切入点表达式
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.lby.service.impl.*.*(..))"/>
</aop:config>
- 建立事务通知和表达式之间的对应关系
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.lby.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
</aop:config>
- 配置事务的属性
是在事务通知的<tx:advice>
内部
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" read-only="false"/>
<tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
属性:propagation:事务传播行为,默认为REQUIRED,
查询操作可用SUPPORTS,增删改用REQUIRED
- 整体
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>-->
<bean id="bankService" class="com.lby.service.impl.BankServiceImpl">
<property name="bankCardDao" ref="bankDao"/>
</bean>
<bean id="bankDao" class="com.lby.dao.impl.BankCardDaoImpl">
<!-- <property name="jdbcTemplate" ref="jdbcTemplate"/>-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- dataSource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="jdbc:sqlserver://localhost:1433;DatabaseName=userinfo"/>
<property name="username" value="widen"/>
<property name="password" value="123456"/>
</bean>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" read-only="false"/>
<tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.lby.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
</aop:config>
</beans>
3 案例
目录结构
1. 新建表
create database bank;
use bank;
create table bankCard(
cardId int primary key auto_increment,
name varchar(50),
money int
);
insert into bankCard(cardId,name,money) values('1234','jack','10000');
insert
into bankCard(cardId,name,money) values('5678','rose','10000');
2.eneity层
public class BankCard implements Serializable {
private String cardId;
private String name;
private long money;
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getMoney() {
return money;
}
public void setMoney(long money) {
this.money = money;
}
@Override
public String toString() {
return "BankCard{" +
"cardId='" + cardId + '\'' +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
3. dao层
a. 创建类JdbcDaoSupport1
/**
* 用于提取dao的重复性代码
*/
public class JdbcDaoSupport1 {
private JdbcTemplate jt;
public void setJt(JdbcTemplate jt) {
this.jt = jt;
}
public JdbcTemplate getJt() {
return jt;
}
public void setDataSource(DataSource dataSource) {
if (jt == null) {
jt = createJdbcTemplate(dataSource);
}
}
private JdbcTemplate createJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
b. 创建接口IBankCardDao
public interface IBankCardDao {
BankCard queryCardById(String id);
void updateBankCard(BankCard bankCard);
}
c. 创建类BankCardDaoImpl
public class BankCardDaoImpl extends JdbcDaoSupport implements IBankCardDao {
public BankCard queryCardById(String id) {
List<BankCard> bankCards = super.getJdbcTemplate().query("select * from bankCard where cardId=?", new BeanPropertyRowMapper<BankCard>(BankCard.class), id);
return bankCards.isEmpty() ? null : bankCards.get(0);
}
public void updateBankCard(BankCard bankCard) {
super.getJdbcTemplate().update("update bankCard set name=?,money=? where cardId=?", bankCard.getName(), bankCard.getMoney(), bankCard.getCardId());
}
}
4.service层
a. 创建接口IBankService
public interface IBankService {
BankCard queryCardById(String id);
void transfer(String fromId, String toId, int money);
}
b. 创建类BankServiceImpl
public class BankServiceImpl implements IBankService {
private IBankCardDao bankCardDao;
public void setBankCardDao(IBankCardDao bankCardDao) {
this.bankCardDao = bankCardDao;
}
public BankCard queryCardById(String cardId) {
return bankCardDao.queryCardById(cardId);
}
public void transfer(String fromId, String toId, int money) {
BankCard from = bankCardDao.queryCardById(fromId);
BankCard to = bankCardDao.queryCardById(toId);
if (from.getMoney() < money) {
System.out.println("余额不足!");
} else {
Long account = from.getMoney() - money;
from.setMoney(account);
account = to.getMoney() + money;
to.setMoney(account);
bankCardDao.updateBankCard(from);
//int i=1/0;
bankCardDao.updateBankCard(to);
System.out.println("转账成功");
}
}
}
5. 测试
a.创建测试类BankServiceTest
/**
* 使用Junit单元测试,测试我们的配置
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class BankServiceTest {
@Autowired
private IBankService bankService;
@Test
public void textTransfer() {
bankService.transfer("1234", "5678", 100);
}
}