当前位置: 首页 > news >正文

网站制作网页专业做礼品团购的网站

网站制作网页,专业做礼品团购的网站,三星单片机开发网站,沧州网站建设公司Spring声明式事务以及事务传播行为 Spring声明式事务1.编程式事务2.使用AOP改造编程式事务3.Spring声明式事务 事务传播行为 如果对数据库事务不太熟悉#xff0c;可以阅读上一篇博客简单回顾一下#xff1a;MySQL事务以及并发访问隔离级别 Spring声明式事务 事务一般添加到… Spring声明式事务以及事务传播行为 Spring声明式事务1.编程式事务2.使用AOP改造编程式事务3.Spring声明式事务 事务传播行为 如果对数据库事务不太熟悉可以阅读上一篇博客简单回顾一下MySQL事务以及并发访问隔离级别 Spring声明式事务 事务一般添加到JavaEE三层结构中的service层业务逻辑层 在Spring进行事务管理操作的两种方式 编程式事务管理 声明式事务管理 **转账案例代码准备**按照以下代码配置完成之后可以进行数据库的操作但不涉及事务。 数据库 create database spring_db; use spring_db; create table account(id int primary key auto_increment,name varchar(20),money double ); insert into account values(null,jack,1000),(null,rose,1000);导入Maven依赖 dependencies!--Spring核心包--dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.2.10.RELEASE/version/dependency!-- 切入点表达式 --dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.4/version/dependency!--mybatis的包--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.6/version/dependency!--Druid数据库连接池--dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.1.16/version/dependency!--数据库驱动包我的MySQL版本是8.0.33--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.33/version/dependency!--spring整合mybatis需要下面两个jar包--dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion5.2.10.RELEASE/version/dependencydependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion1.3.0/version/dependency!-- 引入单元测试的jar包(需要在 4.12以上) --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.2/version/dependency!-- Spring整合junit的jar包 --dependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion5.2.10.RELEASE/version/dependency /dependenciesjdbc.properties配置文件 jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/spring_db jdbc.usernameroot jdbc.password123456MyBatisConfig配置类 public class MyBatisConfig {Beanpublic SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource ds){SqlSessionFactoryBean factoryBean new SqlSessionFactoryBean();//设置pojo的包扫描factoryBean.setTypeAliasesPackage(top.codermao.domain);//设置连接池factoryBean.setDataSource(ds);return factoryBean;}Beanpublic MapperScannerConfigurer mapperScannerConfigurer(){MapperScannerConfigurer msc new MapperScannerConfigurer();//设置dao层的接口扫描msc.setBasePackage(top.codermao.dao);return msc;} }Spring配置类 Configuration ComponentScan(top.codermao) PropertySource(classpath:jdbc.properties) Import(MyBatisConfig.class) public class SpringConfig {Value(${jdbc.driver})private String driver;Value(${jdbc.url})private String url;Value(${jdbc.username})private String username;Value(${jdbc.password})private String password;Beanpublic DataSource getDataSource(){DruidDataSource ds new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(username);ds.setPassword(password);return ds;}}dao层接口 public interface AccountDao {//转出Update(update account set money money - #{money} where id #{outId})int outMoney(Param(outId) int outId, Param(money)double money);//转入Update(update account set money money #{money} where id #{inId})int inMoney(Param(inId) int inId, Param(money)double money); }domain包下实体类 public class Account implements Serializable {private Integer id;private String name;private Double money;public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money money;}Overridepublic String toString() {return Account{ id id , name name \ , money money };}}service层接口 public interface AccountService {//转账业务void transfer(int outId,int inId,double money); }service层实现类 Service public class AccountServiceImpl implements AccountService {Autowiredprivate AccountDao dao;Overridepublic void transfer(int outId, int inId, double money) {try {dao.outMoney(outId, money);//可能在转账过程中发生意外: 转出执行,转入还未执行 // int i 1/0;dao.inMoney(inId, money);} catch (Exception e) {e.printStackTrace();}} }WebApp类充当Controller层负责数据的发送和接收 RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(classes SpringConfig.class) public class WebApp {Autowiredprivate AccountService service;Testpublic void test01(){service.transfer(1, 2, 200);} }1.编程式事务 在学习声明式事务之前我们需要了解编程式事务因为声明式事务是Spring对编程式事务的封装。 所谓编程式事务是指用Spring中事务相关的API用硬编码方式来实现事务 缺点 事务管理代码和业务代码耦合严重后续添加其他业务方法还要重新编写事务代码冗余 所以学习编程式事务就是学习Spring事务管理相关API。 步骤一创建事务管理器 # PlatformTransactionManager(平台事务管理器) 1. 这是一个接口,以下是实现类1). - DataSourceTransactionManager (重点!!!)适用于Spring JDBC或MyBatis2). - HibernateTransactionManager 适用于Hibernate3.0及以上版本 3). - JpaTransactionManager适用于JPA (Java EE 标准之一为POJO提供持久化标准规范并规范了持久化开发的统一API符合JPA规范的开发可以在不同的JPA框架下运行) 2. 此接口定义了事务的基本操作 1). 获取事务 TransactionStatus getTransaction(TransactionDefinition definition)2). 提交事务 void commit(TransactionStatus status) 3). 回滚事务 void rollback(TransactionStatus status) 步骤二定义事务属性TransactionDefinition # TransactionDefinition(定义事务属性) 1. 实现类DefaultTransactionDefinition 2. 此接口定义了事务的基本信息 //2. 创建事务定义对象 DefaultTransactionDefinition td new DefaultTransactionDefinition(); /*设置事务隔离级别0). spring默认隔离级别是跟数据库软件一致1). mysql默认是REPEATABLE_READ2). oracle默认是READ_COMMITTED*/ td.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT); /*设置是否只读1). false,表示读写均可(默认设置,适合增删改操作)2). true,表示只读(适合查,效率高) */ td.setReadOnly(false); /*设置超时时间1). 默认值是-1, 表示永不超时2). 单位是秒 */ td.setTimeout(10); /*设置事务传播行为1. 一般增删改REQUIRED (默认值)2. 一般查询 SUPPORTS */ td.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);步骤三开启事务 # TransactionStatus接口 public final TransactionStatus getTransaction(Nullable TransactionDefinition definition) throws TransactionException 调用事务管理器的getTransaction方法即可开启一个事务 这个方法会返回一个TransactionStatus表示事务状态的一个对象通过TransactionStatus提供的一些方法可以用来控制事务的一些状态比如事务最终是需要回滚还是需要提交。- 获取事务是否处于新开启事务状态- boolean isNewTransaction() - 获取事务是否处于已完成状态- boolean isCompleted() - 获取事务是否处于回滚状态- boolean isRollbackOnly() - 刷新事务状态- void flush() - 获取事务是否具有回滚存储点- boolean hasSavepoint() - 设置事务处于回滚状态- void setRollbackOnly()步骤四执行业务操作 书写业务逻辑代码 步骤五提交 or 回滚 无异常发生提交 dstm.commit(ts);有异常发生回滚 dstm.rollback(ts);对service层AccountServiceImpl的transfer方法添加编程式事务 Service public class AccountServiceImpl implements AccountService {Autowiredprivate AccountDao dao;Autowiredprivate DataSource dataSource;Overridepublic void transfer(int outId, int inId, double money) {//1.创建事务管理器DataSourceTransactionManager dstm new DataSourceTransactionManager();//为事务管理器添加与数据层相同的数据源dstm.setDataSource(dataSource);//2.创建事务定义对象设置隔离级别、传播特性、超时时间...DefaultTransactionDefinition td new DefaultTransactionDefinition();/*设置事务隔离级别0). spring默认隔离级别是跟数据库软件一致 (ISOLATION_DEFAULT)1). mysql默认是REPEATABLE_READ2). oracle默认是READ_COMMITTED*/td.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);/*设置是否为只读事务1). false,表示读写均可(默认设置,适合增删改操作)2). true,表示只读(适合查,效率高)*/td.setReadOnly(false);/*设置超时时间1). 默认值是-1, 表示永不超时2). 单位是秒*/td.setTimeout(10);/*设置事务传播行为1. 一般增删改REQUIRED (默认值)2. 一般查询 SUPPORTS*/td.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);//3.创建事务状态对象用于控制事务执行(了解) - 相当于开启事务TransactionStatus ts dstm.getTransaction(td);try {dao.outMoney(outId, money);//可能在转账过程中发生意外: 转出执行,转入还未执行 // int i 10/0;dao.inMoney(inId, money);dstm.commit(ts);//成功提交} catch (Exception e) {e.printStackTrace();dstm.rollback(ts);//失败回滚}} }2.使用AOP改造编程式事务 硬编码方式添加事务耦合度比较高AOP面向切面编程是动态增强方法如果引入AOP则可以将业务代码和事务代码分开实现解耦。 使用AOP处理编程式事务解决了耦合问题。。但是还是有些不够完美。。AOP处理不具备特例性任何业务添加事务都是一样的操作对某些事务可能对事务属性有一些独特的设置。 步骤一在SpringConfig上添加开启AOP的注解 ... EnableAspectJAutoProxy public class SpringConfig {... }步骤二AccountServiceImpl中transfer中只需要书写业务代码 注意注意: 在aop使用中,切入点方法transfer千万不能自己catch异常 Service public class AccountServiceImpl implements AccountService {/*注意: 在aop使用中,切入点方法千万不能自己catch异常原因: 如果切入点自己catch了异常,那么通知中是调用切入点的地方是不会感知到异常,就不会执行catch了(相当于异常通知失效)解决方案:A方案: 有异常直接抛出,不要catchB方案: 可以catch,但是再new一个异常抛出*/Overridepublic void transfer(int outId, int inId, double money) {dao.outMoney(outId, money);//可能在转账过程中发生意外: 转出执行,转入还未执行//int i 1/0;dao.inMoney(inId, money);} } 步骤三添加TxAdvice 将编程式事务中对事务操作的代码抽取到TxAdvice切面类中 package top.codermao.aspect;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition;import javax.sql.DataSource;Component Aspect public class TxAdvice {Autowiredprivate DataSource dataSource;Pointcut(execution(* top.codermao.service.*Service.transfer(..)))public void pt(){}Around(pt())public Object around(ProceedingJoinPoint pjp){Object result null;//1. 创建事务管理器DataSourceTransactionManager dstm new DataSourceTransactionManager();//为事务管理器设置与数据层相同的数据源!!!dstm.setDataSource(dataSource);//2. 创建事务定义对象 : 隔离级别/传播特性/超时时间...DefaultTransactionDefinition td new DefaultTransactionDefinition();td.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);td.setReadOnly(false);td.setTimeout(10);td.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);//3.创建事务状态对象用于控制事务执行(了解) - 相当于开启事务TransactionStatus ts dstm.getTransaction(td);try{result pjp.proceed();dstm.commit(ts);//成功提交} catch (Throwable e) {e.printStackTrace();dstm.rollback(ts);//失败回滚System.out.println(aop改造编程式事务);}return result;} } 3.Spring声明式事务 spring底层封装了事务切面类TxAdvice, 让开发者声明配置即可用 步骤一在SpringConfig类上添加注解开启Spring事务管理支持 ... EnableTransactionManagement public class SpringConfig {... }步骤二在SpringConfig类中配置事务管理器 ... EnableTransactionManagement public class SpringConfig {...Beanpublic DataSourceTransactionManager getTxManager(DataSource dataSource){//这里使用DataSourceTransactionManager因为使用的是MyBatisDataSourceTransactionManager manager new DataSourceTransactionManager();manager.setDataSource(dataSource);return manager;} }步骤三在需要添加事务的方法上添加Transactional注解使其成为切入点 Transactional注解属性 属性都有默认值 Transactional放置位置不同效果不同 如果放在类的方法上,说明当前方法是切入点如果放在类上,说明当前类的所有方法是切入点如果放在接口的方法上,说明此方法的所有重写方法是切入点 (常用)如果放在接口上,说明此接口的所有实现类的所有方法都是切入点 (常用) 事务传播行为 事务传播行为指的就是当一个事务方法B被另一个事务方法A调用时这个事务方法B应该对待A的事务态度。(B是自己开启一个新事务还是融入A的事务或者不添加事务或者…) Spring事务角色 事务管理员 事务协调员 事务管理员一般是业务层事务A 事务协调员一般是数据层事务B 再次翻译下事务传播行为事务传播行为是指事务协调员对于事务管理员的态度Transactional中的propagation属性 下图来源于B站视频点击进入我觉得讲的很好建议大家去瞅瞅。。 案例往面转账案例添加一个记录日志的功能要求转账成功之后要给account_log表插入谁向谁转了多少钱 添加一个数据表 create table account_log(out_id int,in_id int,money double );dao层接口添加方法 public interface AccountDao {//转出Update(update account set money money - #{money} where id #{outId})int outMoney(Param(outId) int outId, Param(money)double money);//转入Update(update account set money money #{money} where id #{inId})int inMoney(Param(inId) int inId, Param(money)double money);//记录日志Insert(insert into account_log values(#{outId},#{inId},#{money}))void insertLog(Param(outId) int outId, Param(inId) int inId,Param(money) double money); }service层的AccountServiceImpl修改为 Service public class AccountServiceImpl02 implements AccountService {Autowiredprivate AccountDao dao;Autowiredprivate DataSource dataSource;/**转账事务*/Transactional(propagation Propagation.REQUIRED)public void s1(int outId,int inId,double money){dao.outMoney(outId,money);//可能在转账过程中发生意外: 转出执行,转入还未执行dao.inMoney(inId,money);}/**记录日志事务*/Transactional(propagation Propagation.REQUIRES_NEW)public void s2(int outId,int inId,double money){dao.insertLog(outId,inId,money);}/**业务逻辑:1). 如果转账S1操作失败了, S1需要回滚(S1的操作肯定需要事务)如果S1有事务,S1跟随即可, 如果S1没有事务,S1需要自己创建事务所以S1适合设置传播行为属性为REQUIRED2). 如果S1成功S2向数据库中插入日志如果转账S1操作失败了, S2不需要回滚,也向数据库中插入日志所以S2适合设置传播行为属性为REQUIRES_NEW */TransactionalOverridepublic void transfer(int outId, int inId, double money) {s1(outId,inId,money); // int i 10 / 0;s2(outId,inId,money);} }
http://www.sczhlp.com/news/155508/

相关文章:

  • 昆明网站建设询力鼎科技宁波网站建设建站怎么做
  • 如何快速用手机做网站跨境网站
  • 游民星空是谁做的网站华能招标采购电子商务平台
  • 网站后台传不了图片网页源码app
  • 建设网站用什么app视频制作网
  • 闵行区做网站wordpress修改
  • 蔬菜基地做网站合适吗软件设计和软件开发的区别
  • 公司制做网站游戏开发工程师需要学什么
  • 做网站设计工资多少钱jetty网站开发
  • 做地方房产网站怎么样低价网站建设怎么样
  • 网站建设方做网站必须得ipc
  • 在线旅游网站平台有哪些如何在百度上打广告
  • 网站建设的主要步骤有哪些北京百度推广电话
  • 做纪录片卖给视频网站个人博客首页
  • 做外贸要看哪些网站网站模板 html
  • 网站建设160页答案跟做网站相关的法律
  • 2025.10.1总结
  • MySQL COUNT(*)性能对比:MyISAM为何比InnoDB快?全面解析与优化方案
  • 医院网站官方微信精神文明建设成品网站软件大全下载
  • 中天建设中瑞物资网站wordpress 不显示图片
  • 怎样设置一个属于自己的网站广州网站设计联系方式
  • 金融公司网站 html设计平台化
  • 知更鸟wordpress主题桂林seo
  • 成都德阳网站建设天津做网站哪家好
  • 公司网站建设中恒建设集团有限公司百度关键词排名原理
  • phpcms做视频网站浦江网站建设
  • 新都区建设局网站凌点视频素材网
  • 网站建设的辅助软件wordpress代替者开源cms
  • 网站建设内容的重点建设网站如何挂到网上
  • 2018年网站风格找学校的网站