Spring事务的三种实现方式
spring中事务的三种实现方式
1.编程式事务管理
过时了,一般不用,略
2.声明式事务管理
2.1基于 TransactionProxyFactoryBean的声明式事务管理
1创建异常类
1 2 3 4 5 6 7 8 9 10 | public class MyException extends Exception { public MyException() { super (); } public MyException(String message) { super (message); } } |
2 在service层中的转账方法中模拟出异常效果
1 2 3 4 5 6 7 8 9 10 11 12 | public void transfer(Integer from, Integer to, Double money) throws MyException{ cardInfoDao.decreaseMoney(from,money); boolean flag= true ; if (flag) { throw new MyException( "转账出现异常" ); //不要选择try catch 选择 throws } cardInfoDao.increaseMoney(to,money); } |
3 在配置文件中创建事务对象和其代理对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <!-- 事务管理器 --> <bean id= "txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name= "dataSource" ref= "dataSource" /> </bean> <!-- 事务代理工厂 --> <!-- 生成事务代理对象 --> <bean id= "serviceProxy" class = "org.springframework.transaction.interceptor.TransactionProxyFactoryBean" > <property name= "transactionManager" ref= "txManager" ></property> <property name= "target" ref= "cardInfoService" ></property> <property name= "transactionAttributes" > <props> <!-- 主要 key 是方法 ISOLATION_DEFAULT 事务的隔离级别 PROPAGATION_REQUIRED 传播行为 --> <!-- -Exception 表示发生指定异常回滚,+Exception 表示发生指定异常提交 --> <prop key= "transfer" >ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-MyException</prop> </props> </property> </bean> |
注:Spring事务的隔离级别
1、ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别. 另外四个与JDBC的隔离级别相对应
2、ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。 这种隔离级别会产生脏读,不可重复读和幻像读。
3、ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
4、ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。 它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5、ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。 除了防止脏读,不可重复读外,还避免了幻像读。
4 因为有了代理,所以获取accountServiceImpl的时候,拿的是其代理对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Test public void fun() { ClassPathXmlApplicationContext classPathXmlApplicationContext= new ClassPathXmlApplicationContext( "/ApplicationContext.xml" ); ICardInfoService cardInfoService= classPathXmlApplicationContext.getBean( "serviceProxy" ,ICardInfoService. class ); try { cardInfoService.transfer( 1 , 2 , 200.0 ); } catch (MyException e) { e.printStackTrace(); } } |
//预习的内容
2.2基于 @Transactional 注解的声明式事务管理
修改配置文件,添加
1 2 3 4 5 6 7 | <!-- 事务管理器 --> <bean id= "txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name= "dataSource" ref= "comboPooledDataSource" /> </bean> <tx:annotation-driven transaction-manager= "txManager" /> 在service层转账方法中添加注解 |
/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /添加事务注解 @Transactional (isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,rollbackFor=MyException. class ) public void transfer(Integer from, Integer to, Double money) throws MyException{ cardInfoDao.decreaseMoney(from,money); boolean flag= true ; if (flag) { throw new MyException( "转账出现异常a" ); //不要选择try catch 选择 throws } cardInfoDao.increaseMoney(to,money); } |
3.创建配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?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:context= "http://www.springframework.org/schema/context" xmlns:tx= "http://www.springframework.org/schema/tx" xsi:schemaLocation="http: //www.springframework.org/schema/beans http: //www.springframework.org/schema/beans/spring-beans-4.0.xsd http: //www.springframework.org/schema/context http: //www.springframework.org/schema/context/spring-context-4.0.xsd http: //www.springframework.org/schema/tx http: //www.springframework.org/schema/tx/spring-tx.xsd"> <context:annotation-config></context:annotation-config> <context:component-scan base- package = "com.test" /> <!-- 导入db.properties --> <context:property-placeholder location= "db.properties" /> <!-- 创建数据连接池 --> <bean id= "comboPooledDataSource" class = "com.mchange.v2.c3p0.ComboPooledDataSource" > <property name= "driverClass" value= "${driverClass}" /> <property name= "jdbcUrl" value= "${jdbcUrl}" /> <property name= "user" value= "${user}" /> <property name= "password" value= "${password}" /> <property name= "maxPoolSize" value= "${maxPoolSize}" /> </bean> <!-- 创建JdbcTemplate对象 --> <bean id= "jdbcTemplate" class = "org.springframework.jdbc.core.JdbcTemplate" > <constructor-arg name= "dataSource" ref= "comboPooledDataSource" /> </bean> <!-- 1 .创建事务管理器 --> <bean id= "txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name= "dataSource" ref= "comboPooledDataSource" /> </bean> <!-- 开启事务的注解 --> <tx:annotation-driven transaction-manager= "txManager" /> </beans> |
4.测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Test public void fun() { ClassPathXmlApplicationContext classPathXmlApplicationContext= new ClassPathXmlApplicationContext( "/ApplicationContext.xml" ); AccountService accountService= classPathXmlApplicationContext.getBean( "accountServiceImpl" ,AccountService. class ); try { accountService.transfer( 1 , 2 , 250.0 ); } catch (MyException e) { e.printStackTrace(); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)