0
点赞
收藏
分享

微信扫一扫

Spring的事务控制



Spring的事务控制

  • ​​1 基于 XML 的声明式事务控制​​
  • ​​2 基于注解的声明式事务控制​​


1 基于 XML 的声明式事务控制

事务控制最常见的场景为银行的账业务,要么同时成功,要么同时失败,这里搭建一两银行转账业务使用xml声明式事务控制。

1)环境所需pom.xml

<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>

2)controller层:

public class AccountController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = app.getBean(AccountService.class);
accountService.transfer("张无忌", "郭靖", 500);
}
}

3)service层:

public class AccountServiceImpl implements AccountService {

private AccountDao accountDao;

public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}

public void transfer(String outMan, String inMan, double money) { //转账业务
accountDao.out(outMan, money);
int a = 1 / 0; //自造异常
accountDao.in(inMan, money);
}
}

4)dao层:该层使用的是jdbcTemplate模板技术,如果使用其他技术后面applicationContext.xml中配置的平台事务管理器会有差别

public class AccountDaoImpl implements AccountDao {

private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public void out(String outMan, double money) {
jdbcTemplate.update("update account set money=money-? where name=?",money,outMan);
}

public void in(String inMan, double money) {
jdbcTemplate.update("update account set money=money+? where name=?",money,inMan);
}
}

5)applicationContext.xml配置

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
">

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
<property name="user" value="root"/>
<property name="password" value="LIFEILIN"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>

<bean id="accountDao" class="lifeilin.dao.impl.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>

<!-- 1 目标对象,内部方法就是切点-->
<bean id="accountService" class="lifeilin.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>

<!-- 2 配置平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 3 通知 事物的增强 引入命名空间tx-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>

<!-- 4 配置事务aop的织入-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* lifeilin.service.impl.*.*(..))"></aop:advisor>
</aop:config>

</beans>

Spring的事务控制_xml

Spring的事务控制_mysql_02

2 基于注解的声明式事务控制

① 使用 @Transactional 在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离级别、传播行为等。
② 注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。
③ 使用在方法上,不同的方法可以采用不同的事务参数配置。
④ Xml配置文件中要开启事务的注解驱动<tx:annotation-driven />

@Service("accountService")
@Transactional
public class AccountServiceImpl implements AccountService {

@Autowired
private AccountDao accountDao;

@Transactional(isolation = Isolation.READ_COMMITTED ,propagation = Propagation.REQUIRED)
public void transfer(String outMan, String inMan, double money) { //转账业务
accountDao.out(outMan, money);
int a = 1 / 0; //自造异常
accountDao.in(inMan, money);
}
}
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
<property name="user" value="root"/>
<property name="password" value="LIFEILIN"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>


<!-- 2 配置平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 事务的注解驱动-->
<tx:annotation-driven transaction-manager="transactionManager"/>



举报

相关推荐

0 条评论