spring事务锁相关知识
-
Spring事务事件监控前面我们讲到了Spring在进行事务逻辑织入的时候,无论是事务开始,提交或者回滚,都会触发相应的事务事件。本文首先会使用实例进行讲解Spring事务事件是如何使用的,然后会讲解这种使用方式的实现原理。1. 示例对于事务事件,Spring提供了一个注解@TransactionEventListener,将这个注解标注在某个方法上,那么就将这个方法声明为了一个事务事件处理器,而具体的事件类型则是由TransactionalEventListener.phase属性进行定义的。如下是TransactionalEventListener的声明:```@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@EventListenerpublic @interface TransactionalEventListener { // 指定当前标
-
spring 事务深入 -事务失效事务失效的几种原因:1.spring的事务注解@Transactional只能放在public修饰的方法上才起作用,如果放在其他非public(private,protected)方法上,虽然不报错,但是事务不起作用2.如使用mysql且引擎是MyISAM,则事务会不起作用,原因是MyISAM不支持事务,可以改成InnoDB引擎。 3.默认情况下,Spring会对unchecked异常进行事务回滚;如果是checked异常则不回滚。什么是unchecked异常,什么是checked异常?java里面将派生于Error或者RuntimeException(比如空指针,1/0)的异常成为unchecked异常,其他继承自java.lang.Exception的异常统称为checked Exception,如IOException、TimeOutException等 通俗点讲就是,写的代码出现了空指针异常,会被回滚,而文件读写,网络出问题,spring就没法回滚了。 写代码的时候,有些IOException我们的
-
Spring事务原理分析在经历的几轮面试中,每一轮都问到了事务相关的内容,让我越发感到事务的重要性。 如: MySQL事务隔离级别?分别解释下他们的含义,默认的事务隔离级别是什么,Oracle的呢? Spring事务传播级别?分别代表什么含义 Spring事务是如何处理的?自己能写出来吗? 那么今天一起看一下Spring的事务处理方式。我自己想手写事务的时候,发现还是太依赖Spring框架提供的功能了,自己写对我来说还是有一定的难度,在此分析一下Spring的实现方式。 整体结构 Spring初始化概览 Spring整个框架包含很
-
spring boot事务与缓存spring boot事务机制 spring支持声明式事务,用@Tracsational注解在方法上表明该方法需要事务支持。被注解的方法在被调用时开启一个新的事务,当方法无异常结束时,spring会提交这个事务。 属性:propagation,定义事务的生命周期;isolation,隔离,决定事务的完整性;timeout,事务过期时间;readonly,只读事务;rollback,指定哪些异常可以引起事务回滚;norollback,哪些异常不可以引起事务回滚。 spring data JPA对所有的默认方法都开启了事务支持。 1.实体类Person 2.repository实体类PersonRepository 3.service: public class DemoServiceImpl implements DemoService{ @Autowired PersonRepository personRepository; @Transactional(rollbackFor=
spring事务锁相关课程
spring事务锁相关教程
- MySQL 数据库的死锁、事务日志 死锁和事务日志也是数据库事务绕不开的部分,本小节将重点介绍数据库的死锁和事务日志,让大家对死锁和事务日志能有基本的认识。
- 1. 死锁 死锁是指两个或多个事务在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。当多个事务尝试以不同的顺序锁定资源,或者多个事务同时锁定同一个资源,都有可能产生死锁。场景:两个事务同时处理 customer 表两个事务同时执行了第一条 update 语句,更新并锁定了该行数据,紧接着又都执行第二条 update 语句,此时发现该行已经被对方锁定,然后两个事务都等待对方释放锁,同时又持有对方需要的锁,陷入死循环,需要外力介入才能解除死锁。mysql> CREATE TABLE `customer` ( `id` int(11) NOT NULL, `last_name` varchar(30) DEFAULT NULL, `first_name` varchar(30) DEFAULT NULL, `birth_date` date DEFAULT NULL, `gender` char(1) DEFAULT NULL, `balance` decimal(10,0) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8事务1:start transaction;update customer set balance = 100 where id = 1;update customer set balance = 200 where id = 2;commit;事务2:start transaction;update customer set balance = 300 where id = 2;update customer set balance = 400 where id = 1;commit;为了解决死锁问题,数据库实现了各种死锁检测和死锁超时机制。越复杂的存储引擎,越能检测到死锁的循环以来,并返回错误,这是一种比较有效的办法。还有一种解决死锁的办法是:当锁等待超时后,放弃锁请求。InnoDB 存储引擎可以自动检测事务的死锁,并回滚一个或几个事务来防止死锁。但是有些场景 InnoDB是无法检测到死锁的,比如在同一事务中使用 InnoDB 之外的存储引擎、lock tables 设定表锁定的语句,此时要通过设置 innodb_lock_wait_timeout 这个系统参数来解决。通过锁等待超时来解决死锁问题,通常不是好的办法,因为很有可能导致大量事务的锁等待。当发生锁等待超时,数据库会抛出如下报错信息:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 调整 innodb_lock_wait_timeout 的方法有两种:临时:在MySQL中直接用命令行执行-- innodb_lock_wait_timeout的默认值为50秒mysql> show variables like 'innodb_lock_wait_timeout';+--------------------------+-------+| Variable_name | Value |+--------------------------+-------+| innodb_lock_wait_timeout | 50 |+--------------------------+-------+1 row in set (0.00 sec)mysql> set innodb_lock_wait_timeout=51;Query OK, 0 rows affected (0.00 sec)永久:将以下两个参数添加至配置文件 my.cnf,并重启 MySQL:innodb_lock_wait_timeout=50我们在程序设计时,也要尽可能的减小死锁发生的概率。以下是针对 InnoDB 存储引擎减小死锁发生概率的一些建议:类似业务模块,尽可能按照相同的访问顺序来访问,防止产生死锁;同一个事务中,尽可能做到一次锁定需要的所有资源,减少死锁发生概率;同一个事务中,不要使用不同存储引擎的表,比如 MyISAM 和 InnoDB 表出现在同一事务中;尽可能控制事务的大小,减少锁定的资源量和锁定时间长度;对于容易产生死锁的业务模块,尝试升级锁颗粒度,通过表级锁减少死锁发生概率。
- MySQL 服务器级别的锁等待 使用锁来控制资源共享的应用系统,如何处理锁的竞争问题是个头疼事。MySQL 有两个级别的锁等待,服务器级别和存储引擎级别,本节重点介绍服务器级别的锁等待。
- 6.2 一个事务方法调用另一个事务方法时失效 先看下面的实例,我们修改下 OrderService 类,通过一个事务方法调用 createOrder 方法。实例:/** * 订单服务类 */@Service // 注册为服务类public class OrderService { @Autowired private GoodsDao goodsDao; @Autowired private OrderDao orderDao; @Transactional // 开启事务 public int startCreateOrder(Long goodsId, Long count) throws Exception { return this.createOrder(goodsId, count); } /** * 下单 * * @param goodsId 购买商品id * @param count 购买商品数量 * @return 生成订单数 */ @Transactional(rollbackFor = Exception.class) // 抛出异常即回滚 public int createOrder(Long goodsId, Long count) throws Exception { // 锁定商品库存 GoodsDo goods = goodsDao.selectForUpdate(goodsId); // 扣减库存 Long newNum = goods.getNum() - count; goods.setNum(newNum); goodsDao.update(goods); if (count > goods.getNum()) { // 非受检查异常抛出时,会回滚 throw new Exception(); } // 生成订单 OrderDo order = new OrderDo(); order.setGoodsId(goodsId); order.setCount(count); int affectRows = orderDao.insert(order); return affectRows; }}此时我们在测试类中通过 startCreateOrder 方法再去调用 createOrder 方法,代码如下:实例:/** * 订单测试 */@SpringBootTestclass OrderTest { @Autowired private OrderService orderService; /** * 创建订单测试 */ @Test void testCreateOrder() throws Exception { // 购买id为1的商品1份 int affectRows = orderService.startCreateOrder(1L, 100L); assertEquals(1, affectRows); }}startCreateOrder 和 createOrder 方法都是事务方法,且这两个方法事务特性不同 (一个没有 rollbackFor=Exception.class),如果我们调用 startTransaction 方法,则 createOrder 中的事务并不会生效。也就是说,如果在同一个类中,一个事务方法调用另一个事务方法,可能会导致被调用的事务方法的事务失效!这是因为 Spring 的声明式事务使用了代理,具体机制此处不再探讨,但是一定要注意规避这种事务失效的场景。
- 3. 悲观锁 Pessimistic Locking 悲观地认为并发的事务时时会发生,总是担心隔离机制不能很好的保证事务之间的安全性。基本思想就是当一个事务读取某一条记录后,就会把这条记录锁住,如果其它的事务要想更新,必须等以前的事务提交或者回滚解除锁;悲观锁的实现,一般依靠数据库提供的锁机制。只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在系统中实现了加锁机制,也无法保证外部系统不会修改数据。SQL 的 select 语句中有一个 for 语法关键字:SELECT * from student where stuName='Hibernate' for UPDATE其作用就是锁定这条记录,当前事务没有结束之前,其它的事务不能在这条记录上进行数据更新操作。
- 9.1 事务管理器 transactionManager 在 xml 文件中对应 <transactionManager type="JDBC"/>,其中 type 属性对应了事务管理器的两种类型,分别是JDBC和MANAGED。JDBC :直接使用了 JDBC 的提交和回滚机制。MANAGED:让容器来管理事务的整个生命周期,例如 spring 容器。提示: 如果你使用 spring 作为容器,那么 transactionManager 会被自动配置且可用。
spring事务锁相关搜索
-
s line
safari浏览器
samba
SAMP
samplerate
sandbox
sanitize
saper
sas
sass
save
smarty模板
smil
smtp
snapshot
snd
snmptrap
soap
soapclient
soap协议