Java Spring 声明式事务详解
项目结构:
表结构:
基于xml的声明式事务配置
IAccountDao.java:
package tx.dao; import java.math.BigDecimal; public interface IAccountDao { void add(String name, BigDecimal money); void sub(String name, BigDecimal money); }
AccountDaoImpl.java:
package tx.service.impl; import tx.dao.IAccountDao; import tx.service.IAccountService; import java.math.BigDecimal; public class AccountServiceImpl implements IAccountService { private IAccountDao accountDao; public void setAccountDao(IAccountDao accountDao) { this.accountDao = accountDao; } @Override public void tran(String from, String to, BigDecimal money) { accountDao.sub(from, money); accountDao.add(to, money); } }
IAccountService.java:
package tx.service; import java.math.BigDecimal; public interface IAccountService { void tran(String from, String to, BigDecimal money); }
AccountDaoImpl.java:
package tx.dao.impl; import org.springframework.jdbc.core.JdbcTemplate; import tx.dao.IAccountDao; import java.math.BigDecimal; public class AccountDaoImpl implements IAccountDao { private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public void add(String name, BigDecimal money) { jdbcTemplate.update("update account set balance = balance + ? where name = ? ", money.toString(), name); } @Override public void sub(String name, BigDecimal money) { jdbcTemplate.update("update account set balance = balance - ? where name = ? ", money.toString(), name); } }
<?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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <!--配置数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="19834044876"/> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> </bean> <!--创建事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--注入数据源--> <property name="dataSource" ref="dataSource"/> </bean> <!--配置jdbcTemplate对象--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!--注入dataSource--> <property name="dataSource" ref="dataSource"/> </bean> <!--将JdbcTemplate注入到AccountDao中--> <bean id="accountDao" class="tx.dao.impl.AccountDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> <!--将AccountDao注入到AccountService中--> <bean id="accountService" class="tx.service.impl.AccountServiceImpl"> <property name="accountDao" ref="accountDao"/> </bean> <!--配置事务通知--> <tx:advice id="txAdvice"> <!--配置事务参数--> <tx:attributes> <!--指定哪些方法上面添加事务--> <tx:method name="tran"/> <!-- name="*", name="tran*", name="*tran", ... --> </tx:attributes> </tx:advice> <!--配置切入点和切面--> <aop:config> <!--配置切入点--> <aop:pointcut id="pointCut" expression="execution(* tx.service.IAccountService.*(..))"/> <!--配置通知--> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/> </aop:config> </beans>
ApplicationContext context = new ClassPathXmlApplicationContext("tx.xml"); IAccountService accountService = context.getBean("accountService", IAccountService.class); accountService.tran("小明", "小红", new BigDecimal(500));
完全注解(零xml)方式配置
IAccountDao.java:
package tx.dao; import java.math.BigDecimal; public interface IAccountDao { void add(String name, BigDecimal money); void sub(String name, BigDecimal money); }
AccountDaoImpl.java:
package tx.dao.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import tx.dao.IAccountDao; import java.math.BigDecimal; @Repository public class AccountDaoImpl implements IAccountDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public void add(String name, BigDecimal money) { jdbcTemplate.update("update account set balance = balance + ? where name = ? ", money.toString(), name); } @Override public void sub(String name, BigDecimal money) { jdbcTemplate.update("update account set balance = balance - ? where name = ? ", money.toString(), name); } }
IAccountService.java:
package tx.service; import java.math.BigDecimal; public interface IAccountService { void tran(String from, String to, BigDecimal money); }
AccountServiceImpl.java:
package tx.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import tx.dao.IAccountDao; import tx.service.IAccountService; import java.math.BigDecimal; @Service @Transactional public class AccountServiceImpl implements IAccountService { @Autowired private IAccountDao accountDao; @Override public void tran(String from, String to, BigDecimal money) { accountDao.sub(from, money); accountDao.add(to, money); } }
TXConfig.java
package tx.config; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import tx.service.IAccountService; import tx.service.impl.AccountServiceImpl; import javax.sql.DataSource; @Configuration @ComponentScan(basePackages = "tx") @EnableTransactionManagement public class TXConfig { /** * 配置数据源 */ @Bean public DataSource getDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/test?useSSL=false"); dataSource.setUsername("root"); dataSource.setPassword("19834044876"); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); return dataSource; } /** * 创建事务管理器 */ @Bean public DataSourceTransactionManager getTransactionManager() { return new DataSourceTransactionManager(getDataSource()); } /** * 配置jdbcTemplate对象 */ @Bean public JdbcTemplate getJdbcTemplate() { return new JdbcTemplate(getDataSource()); } @Bean(name = "accountService") public IAccountService getAccountService() { return new AccountServiceImpl(); } }
ApplicationContext context = new AnnotationConfigApplicationContext(TXConfig.class); IAccountService accountService = context.getBean("accountService", IAccountService.class); accountService.tran("小明", "小红", new BigDecimal(500));
事务参数
no-rollback-for
指定碰到哪些异常不需要回滚
rollback-for
指定碰到哪些异常需要回滚
read-only
设置事务为只读事务
timeout
以秒为单位,设置事务超出指定时常后自动回滚
默认为-1,即不管事务运行多久都不回滚
isolation
事务的隔离级别
默认为DEFAULT,即使用当前数据库的隔离级别
propagation
事务的传播行为
默认为REQUIRED
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注猪先飞的更多内容!
相关文章
- 这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
Spring Cloud 中@FeignClient注解中的contextId属性详解
这篇文章主要介绍了Spring Cloud 中@FeignClient注解中的contextId属性详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-25Springboot如何实现Web系统License授权认证
这篇文章主要介绍了Springboot如何实现Web系统License授权认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-28- 本文主要对C# 类的声明进行详细介绍。具有一定的参考价值,下面跟着小编一起来看下吧...2020-06-25
如何在Spring WebFlux的任何地方获取Request对象
这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26- 这篇文章主要介绍了详解SpringCloudGateway内存泄漏问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-16
- 因此,正确的原子操作是真正被执行过的。是物理执行。在当前事务中确实能看到插入的记录。最后只不过删除了。但是AUTO_INCREMENT不会应删除而改变值。1、为什么auto_increament没有回滚?因为innodb的auto_increament的...2014-05-31
- @Autowired 注解的主要功能就是完成自动注入,使用也非常简单,但这篇文章主要给大家介绍了关于Spring为什么不推荐使用@Autowired注解的相关资料,需要的朋友可以参考下...2021-11-03
Springboot如何使用mybatis实现拦截SQL分页
这篇文章主要介绍了Springboot使用mybatis实现拦截SQL分页,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-19- 只要是写过点JS代码,很简单一个var 就完事了。那对于JS编译器背后它又发生了什么呢?那就一步步通过代码来讲起。 复制代码 代码如下: x = 1; alert(x); var y = function() { alert(x); var x = 2; alert(x); } y();...2013-10-13
- 这篇文章主要介绍了SpringMVC文件上传原理及实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-15
Spring Data JPA 关键字Exists的用法说明
这篇文章主要介绍了Spring Data JPA 关键字Exists的用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-10解决@Transactional注解事务不回滚不起作用的问题
这篇文章主要介绍了解决@Transactional注解事务不回滚不起作用的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-23网页头部声明lang=”zh-cn”、lang=“zh”、lang=“zh-cmn-Hans”区别
我们现在使用的软件都会自动在前面加一个申明了,那么在网页头部声明lang=”zh-cn”、lang=“zh”、lang=“zh-cmn-Hans”区别是什么呢?下面我们就一起来看看吧. 单...2016-09-20tomcat启动完成执行 某个方法 定时任务(Spring)操作
这篇文章主要介绍了tomcat启动完成执行 某个方法 定时任务(Spring)操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-25使用Maven 搭建 Spring MVC 本地部署Tomcat的详细教程
这篇文章主要介绍了使用Maven 搭建 Spring MVC 本地部署Tomcat,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-16- 这篇文章主要介绍了Spring Cloud负载均衡及远程调用实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2021-09-18
- 这篇文章主要介绍了SpringMvc自动装箱及GET请求参数原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-19
- 这篇文章主要介绍了Springboot使用thymeleaf动态模板实现刷新,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-08-31
- 这篇文章主要介绍了SpringMvc获取请求头请求体消息过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-17