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

海口高端品牌网站建设国内新闻热点事件

海口高端品牌网站建设,国内新闻热点事件,苏州企业宣传片制作公司,网上商城是什么软件✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Spring专栏 ✨特色专栏: M…

Springgif.gif

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉
🍎个人主页:Leo的博客
💞当前专栏: Spring专栏
✨特色专栏: MySQL学习
🥭本文内容:Spring5学习笔记—Spring事务处理
🖥️个人小站 :个人博客,欢迎大家访问
📚个人知识库: 知识库,欢迎大家访问

1. 什么是事务

事务是逻辑上的一组操作,要么都执行,要么都不执行。

相信大家应该都能背上面这句话了,下面我结合我们日常的真实开发来谈一谈。

我们系统的每个业务方法可能包括了多个原子性的数据库操作,比如下面的 save() 方法中就有两个原子性的数据库操作。这些原子性的数据库操作是有依赖的,它们要么都执行,要不就都不执行。

	public void save() {personDao.save(student);personDetailDao.save(studentDetail);}

另外,需要格外注意的是:事务能否生效数据库引擎是否支持事务是关键。比如常用的 MySQL 数据库默认使用支持事务的 innodb引擎。但是,如果把数据库引擎变为 myisam,那么程序也就不再支持事务了

事务是保证业务操作完整性的一种数据库机制。事务的4特点: A C I D
1. A(Atomicity) 	原子性 
2. C(Consistency) 	一致性
3. I(Isolation)		隔离性
4. D(durability) 	持久性
  1. 原子性Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  2. 一致性Consistency):执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  3. 隔离性Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  4. 持久性Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

🌈:只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。也就是说 A、I、D 是手段,C 是目的!

image-20230828202040602

2. Spring对事务的支持

Spring支持的两种事务管理

3.1 编程式事务管理

通过 TransactionTemplate或者TransactionManager手动管理事务,实际应用中很少使用。

使用TransactionTemplate 进行编程式事务管理的示例代码如下:

@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {transactionTemplate.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {try {// ....  业务代码} catch (Exception e){//回滚transactionStatus.setRollbackOnly();}}});
}

使用 TransactionManager 进行编程式事务管理的示例代码如下:

@Autowired
private PlatformTransactionManager transactionManager;public void testTransaction() {TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());try {// ....  业务代码transactionManager.commit(status);} catch (Exception e) {transactionManager.rollback(status);}
}

3.2 声明式事务管理

这一种方式实际上比较推荐的,实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)。

使用 @Transactional注解进行事务管理的示例代码如下:

public class Test {@Transactional(propagation = Propagation.REQUIRED)public void method() {/** 做业务**/MethodOne mb = new MethodOne();MethodOne mc = new MethodOne();mb.bMethod();mc.cMethod();}
}

Spring主要通过以下三个接口对事务进行管理

  • PlatformTransactionManager:(平台)事务管理器,Spring 事务策略的核心。
  • TransactionDefinition:事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。
  • TransactionStatus:事务运行状态。

我们可以把 PlatformTransactionManager 接口可以被看作是事务上层的管理者,而 TransactionDefinitionTransactionStatus 这两个接口可以看作是事务的描述。

PlatformTransactionManager 会根据 TransactionDefinition 的定义比如事务超时时间、隔离级别、传播行为等来进行事务管理 ,而 TransactionStatus 接口则提供了一些方法来获取事务相应的状态比如是否新事务、是否可以回滚等等。

1. PlatformTransactionManager

简称事务管理接口

image-20230828200844565

PlatformTransactionManager接口中定义了三个方法:

package org.springframework.transaction;import org.springframework.lang.Nullable;public interface PlatformTransactionManager {//获得事务TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;//提交事务void commit(TransactionStatus var1) throws TransactionException;//回滚事务void rollback(TransactionStatus var1) throws TransactionException;
}
2. TransactionDefinition

简称事务属性

事务管理器接口 PlatformTransactionManager 通过 getTransaction(TransactionDefinition definition) 方法来得到一个事务,这个方法里面的参数是 TransactionDefinition 类 ,这个类就定义了一些基本的事务属性。

什么是事务属性呢? 事务属性可以理解成事务的一些基本配置,描述了事务策略如何应用到方法上。

事务属性包含了 5 个方面:

  • 隔离级别
  • 传播行为
  • 回滚规则
  • 是否只读
  • 事务超时

TransactionDefinition 接口中定义了 5 个方法以及一些表示事务属性的常量比如隔离级别、传播行为等等。

package org.springframework.transaction;import org.springframework.lang.Nullable;public interface TransactionDefinition {int PROPAGATION_REQUIRED = 0;int PROPAGATION_SUPPORTS = 1;int PROPAGATION_MANDATORY = 2;int PROPAGATION_REQUIRES_NEW = 3;int PROPAGATION_NOT_SUPPORTED = 4;int PROPAGATION_NEVER = 5;int PROPAGATION_NESTED = 6;int ISOLATION_DEFAULT = -1;int ISOLATION_READ_UNCOMMITTED = 1;int ISOLATION_READ_COMMITTED = 2;int ISOLATION_REPEATABLE_READ = 4;int ISOLATION_SERIALIZABLE = 8;int TIMEOUT_DEFAULT = -1;// 返回事务的传播行为,默认值为 REQUIRED。int getPropagationBehavior();//返回事务的隔离级别,默认值是 DEFAULTint getIsolationLevel();// 返回事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。int getTimeout();// 返回是否为只读事务,默认值为 falseboolean isReadOnly();@NullableString getName();
}
3. TransactionStatus

简称事务状态

TransactionStatus接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信息。

PlatformTransactionManager.getTransaction(…)方法返回一个 TransactionStatus 对象。

TransactionStatus 接口内容如下:

public interface TransactionStatus{boolean isNewTransaction(); // 是否是新的事务boolean hasSavepoint(); // 是否有恢复点void setRollbackOnly();  // 设置为只回滚boolean isRollbackOnly(); // 是否为只回滚boolean isCompleted; // 是否已完成
}

Spring对事务的支持

⚠️ 再提醒一次:你的程序是否支持事务首先取决于数据库 ,比如使用 MySQL 的话,如果你选择的是 innodb 引擎,那么恭喜你,是可以支持事务的。但是,如果你的 MySQL 数据库使用的是 myisam 引擎的话,那不好意思,从根上就是不支持事务的。

MySQL 怎么保证原子性的?

我们知道如果想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,在 MySQL 中,恢复机制是通过 回滚日志(undo log) 实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,我们直接利用 回滚日志 中的信息将数据回滚到修改之前的样子即可!并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚之前未完成的事务。

Spring对事务控制

JDBC:
Connection.setAutoCommit(false);
Connection.commit();
Connection.rollback();
Mybatis:
Mybatis自动开启事务

​ sqlSession(Connection).commit();
​ sqlSession(Connection).rollback();

结论:控制事务的底层 都是Connection对象完成的。

3. Spring控制事务的开发步骤:

Spring是通过AOP的方式进行事务的开发、

3.1 目标对象

public class XXXUserServiceImpl{private xxxDAO xxxDAOset get1. 原始对象 ---》 原始方法 ---》核心功能 (业务处理+DAO调用)2. DAO作为Service的成员变量,依赖注入的方式进行赋值
}

3.2 额外功能

1. org.springframework.jdbc.datasource.DataSourceTransactionManager
2. 注入DataSource 
1. MethodInterceptorpublic Object invoke(MethodInvocation invocation){//原理:try{Connection.setAutoCommit(false);Object ret = invocation.proceed();Connection.commit();}catch(Exception e){Connection.rollback();}return ret;}
2. @Aspect@Around 

3.3 切入点

@Transactional
事务的额外功能加入给哪些业务方法。

  1. 类上:类中所有的方法都会加入事务
  2. 方法上:这个方法会加入事务

3.4 组装切面

1. 切入点
2. 额外功能<tx:annotation-driven transaction-manager=""/>

4. Spring控制事务的真实编码:

  • 搭建开发环境:

    <dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.1.14.RELEASE</version>
    </dependency>
    
  • 编码:

    <!-- 原始对象 -->
    <bean id="userService" class="com.baizhiedu.service.UserServiceImpl"><property name="userDAO" ref="userDAO"/>
    </bean><!--DataSourceTransactionManager-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 需要Connection 而Connection又在dataSource里 --><property name="dataSource" ref="dataSource"/>
    </bean>@Transactional
    public class UserServiceImpl implements UserService {private UserDAO userDAO;
    <!-- 告诉Spring开启基于注解的事务管理 -->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
    
  • 细节:

    <tx:annotation-driven transaction-manager="dataSourceTransactionManager" proxy-target-class="true"/>
    进行动态代理底层实现的切换   proxy-target-class默认	false JDKtrue  Cglib 
    

5. Spring的事务属性

事务属性简称 Transaction Attribute

5.1 什么是事务属性?

属性:描述物体特征的一系列值
性别 身高 体重 …
事务属性:描述事务特征的一系列值

  1. 隔离属性
  2. 传播属性
  3. 只读属性
  4. 超时属性
  5. 异常属性

5.2 如何添加事务属性

@Transactional(isloation=,propagation=,readOnly=,timeout=,rollbackFor=,noRollbackFor=,)

5.3 事务属性详解

1. 隔离属性 (ISOLATION)

  • 隔离属性的概念

    概念:他描述了事务解决并发问题的特征
    1. 什么是并发多个事务(用户)在同一时间,访问操作了相同的数据同一时间:0.000几秒 微小前 微小后
    2. 并发会产生那些问题1. 脏读2. 不可重复读3. 幻影读
    3. 并发问题如何解决通过隔离属性解决,隔离属性中设置不同的值,解决并发处理过程中的问题。
    
  • 事务并发会产生的问题

    • 脏读

      一个事务,读取了另一个事务中没有提交的数据。会在本事务中产生数据不一致的问题
      解决方案 @Transactional(isolation=Isolation.READ_COMMITTED)

  • 不可重复读

    一个事务中,多次读取相同的数据,但是读取结果不一样。会在本事务中产生数据不一致的问题
    注意:1 不是脏读 2 一个事务中
    解决方案 @Transactional(isolation=Isolation.REPEATABLE_READ)
    本质: 一把行锁

    • 幻影读

      一个事务中,多次对整表进行查询统计,但是结果不一样,会在本事务中产生数据不一致的问题
      解决方案 @Transactional(isolation=Isolation.SERIALIZABLE)
      本质:表锁

    • 总结

      并发安全: SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED
      运行效率: READ_COMMITTED > REPEATABLE_READ > SERIALIZABLE

  • 数据库对于隔离属性的支持

    隔离属性值MySQLOracle
    ISOLATION_READ_COMMITTED
    IOSLATION_REPEATABLE_READ
    ISOLATION_SERIALIZABLE

    Oracle不支持REPEATABLE_READ值 如何解决不可重复读?
    采用的是多版本比对的方式 解决不可重复读的问题

  • 默认隔离属性

    ISOLATION_DEFAULT:会调用不同数据库所设置的默认隔离属性

    MySQL : REPEATABLE_READ
    Oracle: READ_COMMITTED

  • 查看数据库默认隔离属性

    • MySQL

        select @@tx_isolation;
      
    • Oracle

      SELECT s.sid, s.serial#,CASE BITAND(t.flag, POWER(2, 28))WHEN 0 THEN 'READ COMMITTED'ELSE 'SERIALIZABLE'END AS isolation_levelFROM v$transaction t JOIN v$session s ON t.addr = s.taddrAND s.sid = sys_context('USERENV', 'SID');
      
  • 隔离属性在实战中的建议

    推荐使用Spring指定的ISOLATION_DEFAULT

    1. MySQL repeatable_read
    2. Oracle read_commited

    未来实战中,并发访问情况,很少

    如果真遇到并发问题,乐观锁
    Hibernate(JPA) Version
    MyBatis 通过拦截器自定义开发

2. 传播属性(PROPAGATION)

  • 传播属性的概念:

    概念:他描述了事务解决嵌套问题的特征

    什么叫做事务的嵌套:他指的是一个大的事务中,包含了若干个小的事务

    问题:大事务中融入了很多小的事务,他们彼此影响,最终就会导致外部大的事务,丧失了事务的原子性

image-20230828155139656

  • 传播属性的值极其用法:

    传播属性的值外部不存在事务外部存在事务用法备注
    REQUIRED开启新的事务融合到外部事务中@Transactional(propagation = Propagation.REQUIRED)增删改方法
    SUPPORTS不开启事务融合到外部事务中@Transactional(propagation = Propagation.SUPPORTS)查询方法
    REQUIRES_NEW开启新的事务挂起外部事务,创建新的事务@Transactional(propagation = Propagation.REQUIRES_NEW)日志记录方法中
    NOT_SUPPORTED不开启事务挂起外部事务@Transactional(propagation = Propagation.NOT_SUPPORTED)及其不常用
    NEVER不开启事务抛出异常@Transactional(propagation = Propagation.NEVER)及其不常用
    MANDATORY抛出异常融合到外部事务中@Transactional(propagation = Propagation.MANDATORY)及其不常用
  • 默认传播属性:

    Propagation.REQUIRED

  • 推荐传播属性的使用方式

    增删改 方法:直接使用默认值REQUIRED
    查询 操作:显示指定传播属性的值为SUPPORTS

3. 只读属性(readOnly)

针对于只进行查询操作的业务方法,可以加入只读属性,提供运行效率

默认值:false

4. 超时属性(timeout)

指定了事务等待的最长时间

  1. 为什么事务进行等待?
    当前事务访问数据时,有可能访问的数据被别的事务进行加锁的处理,那么此时本事务就必须进行等待。
  2. 等待时间 秒
  3. 如何应用 @Transactional(timeout=2)
  4. 超时属性的默认值 -1
    最终由对应的数据库来指定

5. 异常属性

Spring事务处理过程中
默认 对于RuntimeException及其子类 采用的是回滚的策略
默认 对于Exception及其子类 采用的是提交的策略

rollbackFor = {java.lang.Exception,xxx,xxx}
noRollbackFor = {java.lang.RuntimeException,xxx,xx}

@Transactional(rollbackFor = {java.lang.Exception.class},noRollbackFor = {java.lang.RuntimeException.class})

建议:实战中使用RuntimeExceptin及其子类 使用事务异常属性的默认值

5.4 事务属性常见配置总结

  1. 隔离属性 默认值
  2. 传播属性 Required(默认值) 增删改 Supports 查询操作
  3. 只读属性 readOnly false 增删改 true 查询操作
  4. 超时属性 默认值 -1
  5. 异常属性 默认值

增删改操作 @Transactional
查询操作 @Transactional(propagation=Propagation.SUPPORTS,readOnly=true)

5.5 基于标签的事务配置方式(事务开发的第二种形式)

  • 基于注解 @Transaction的事务配置回顾

    <bean id="userService" class="com.baizhiedu.service.UserServiceImpl"><property name="userDAO" ref="userDAO"/>
    </bean><!--DataSourceTransactionManager-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
    </bean>@Transactional(isolation=,propagation=,...)
    public class UserServiceImpl implements UserService {private UserDAO userDAO;<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
    
  • 基于标签的事务配置:

    <bean id="userService" class="com.baizhiedu.service.UserServiceImpl"><property name="userDAO" ref="userDAO"/>
    </bean><!--DataSourceTransactionManager-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
    </bean><!-- 事务属性 -->
    <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager"><tx:attributes><tx:method name="register" isoloation="",propagation=""></tx:method><tx:method name="login" .....></tx:method>等效于 @Transactional(isolation=,propagation=,)public void register(){}</tx:attributes>
    </tx:advice><aop:config><aop:pointcut id="pc" expression="execution(* com.baizhiedu.service.UserServiceImpl.register(..))"></aop:pointcut><aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
    </aop:config>
    
  • 基于标签的事务配置在实战中的应用方式

    <bean id="userService" class="com.baizhiedu.service.UserServiceImpl"><property name="userDAO" ref="userDAO"/>
    </bean><!--DataSourceTransactionManager-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
    </bean>编程时候 service中负责进行增删改操作的方法 都以modify开头查询操作 命名无所谓 
    <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager"><tx:attributes><tx:method name="register"></tx:method><tx:method name="modify*"></tx:method><tx:method name="*" propagation="SUPPORTS"  read-only="true"></tx:method></tx:attributes>
    </tx:advice>应用的过程中,service放置到service包中
    <aop:config><aop:pointcut id="pc" expression="execution(* com.baizhiedu.service..*.*(..))"></aop:pointcut><aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
    </aop:config>查询操作 命名无所谓 
    <tx:advice id="txAdvice" transacation-manager="dataSourceTransactionManager"><tx:attributes><tx:method name="register"></tx:method><tx:method name="modify*"></tx:method><tx:method name="*" propagation="SUPPORTS"  read-only="true"></tx:method></tx:attributes>
    </tx:advice>应用的过程中,service放置到service包中
    <aop:config><aop:pointcut id="pc" expression="execution(* com.baizhiedu.service..*.*(..))"></aop:pointcut><aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
    </aop:config>
    
http://www.dt0577.cn/news/12915.html

相关文章:

  • 求购做网站网页制作模板的网站
  • 网络技术与网站建设株洲网站设计
  • GTA5房产网站建设中自建网站平台有哪些
  • 破解软件库合集资料网址大全优化网络培训
  • 淘宝客网站主题下载深圳关键词排名优化系统
  • 做网站盈利靠谱的广告联盟
  • 有什么好的网站做数学题吗青岛网站优化公司
  • 网站模版怎么做百度识图查图片
  • 企业门户网站功能列表aso推广
  • 做网站的标性网站做优化好还是推广好
  • 江西城乡建设培训中心网站代做百度首页排名价格
  • 杭州电商直播培训班怎么做网站优化
  • 简述网站开发的基本流程图百度商店应用市场
  • php 企业网站 后台图片上传外贸网站大全
  • 江门官网建站公司网络推广理实一体化软件
  • 网站开发合同书百度信息流推广技巧
  • 电商网站运营团队建设方案模板广州seo公司哪个比较好
  • 做设计外包的网站长沙百度推广运营公司
  • 建站工具 开源试分析网站推广和优化的原因
  • 三语网站建设google优化推广
  • chn域名注册网站百度资源搜索平台官网
  • 沈阳搜索排名公司优化大师win10能用吗
  • 嘉定区整站seo十大排名广东宣布即时优化调整
  • 百度网站如何做外贸企业网站设计公司
  • 企业网站建设技术班级优化大师电脑版
  • wordpress 分页东莞seo托管
  • 动态Js文件 做网站标题泉州seo技术
  • 金融网站建设谷歌推广怎么样
  • 日本室内设计网站大全吴中seo页面优化推广
  • 自己搭建公司网站长春百度推广电话