参考帖子:http://blog.csdn.net/winy_lm/article/details/50403264
举个例子: 假设商品表单products 内有一个存放商品数量的quantity ,在订单成立之前必须先确定quantity 商品数量是否足够(quantity>0) ,
然后才把数量更新为1。
不安全的做法:
SELECT quantity FROM products WHERE id=3;
UPDATE products SET quantity = 1 WHERE id=3;
为什么不安全呢?
少量的状况下或许不会有问题,但是大量的数据存取「铁定」会出问题。
如果我们需要在quantity>0 的情况下才能扣库存,假设程序在第一行SELECT 读到的quantity 是2 ,看起来数字没有错,但是当MySQL 正准备要UPDATE 的时候,可能已经有人把库存扣成0 了,但是程序却浑然不知,将错就错的UPDATE 下去了。
因此必须透过的事务机制来确保读取及提交的数据都是正确的。
实际测试:
loading很久后如下
项目中测试:
Xml:
Service:
在项目中无需另外写SET AUTOCOMMIT=0; BEGIN WORK; 只需在查询语句后面加上for update
因为@Transactional已经帮我们完成了这些操作
Controller:
测试方法
同一个项目在两个Tomcat中启动,因为需要在其中一个方法内打断点,所以需要在两个eclipse中操作或者打成war包放入Tomcat/webapps中启动,同时开启两个Tomcat需要更改其中一个的端口号避免端口号占用的问题。
两个项目都开启好之后,下面正式开启测试。
库存不足时,两个项目的显示:
库存为1时,其中一个进入方法打断点之后,另一个进行同样的操作:
在8081的这个上打上断点,断点打在findById(for update)之后
然后进入8080,发现8081断点不放开,这边就一直在加载中。。
放开断点之后,8081库存-1 成功,8080也加载完成,显示库存不足,达到我们的要求
写在后面:
测试去除@Transactional注解之后的效果,在同样的操作下最后都显示“库存 -1 : success”, 这是因为没有Transactional注解下,没有SET AUTOCOMMIT=0; BEGIN WORK;的效果, 导致select..for update没有生效。
相关推荐
1. **什么是事务** 事务是一系列数据库操作的逻辑单元,这些操作要么全部成功执行,要么全部不执行。在事务中,每个操作都是原子性的,即不可分割,要么全部完成,要么全部回滚,以保持数据的一致性。 2. **事务...
- **JTA (Java Transaction API)**:提供了跨多个资源管理器的事务管理功能。 - **JDBC事务管理**:适用于单一数据库资源的简单事务管理。 - **EJB容器事务管理**:为EJB组件提供透明的事务支持。 - **Spring框架...
4. **间隙锁(Gap Locks)和Next-Key Locks**:为了防止“幻读”问题,InnoDB会自动在会话事务中加上间隙锁,锁定数据行之间的“间隙”,并使用Next-Key Locks来锁定索引键及其之前的数据项,从而保证数据的一致性。...
1. 锁定:SQL Server 2000使用多种类型的锁,如共享锁(读锁)、排他锁(写锁)、更新锁等,来防止多个事务对同一资源的并发修改。锁定策略可以是行级、页级或表级,取决于事务的隔离级别。 2. 快照隔离:这种隔离...
在数据库管理中,事务(Transaction)和锁定(Locking)是保证数据完整性和一致性的重要机制。事务被视为一系列操作的集合,这些操作要么全部成功,要么全部失败,以确保数据状态的统一性和可靠性。锁定机制则用来...
隔离级别定义了并发事务之间的数据可见性,如`Isolation.READ_UNCOMMITTED`(读未提交)、`Isolation.REPEATABLE_READ`(可重复读)等。不同的隔离级别可以防止脏读、不可重复读和幻读等问题。 4. 只读事务...
1. **行锁(Row Locks)**:锁定特定数据行,减少锁的粒度,提高并发性。 2. **页锁(Page Locks)**:锁定数据页,比行锁粒度稍大,能减少锁定开销。 3. **表锁(Table Locks)**:锁定整个表,适用于全表扫描等...
事务会在修改数据的第一条语句处隐式开始(也就是得到 TX 锁的第一条语句)。也可以使用 SET TRANSACTION 或 DBMS_TRANSACTION 包来显式地开始一个事务。 事务控制语句包括: 1. COMMIT:结束事务,并使得已做的...
- **乐观锁**:假设数据不太可能发生冲突,仅在提交事务时检查数据是否被其他事务修改。 - **版本号**:通过记录数据的版本号来实现乐观锁。 - **时间戳**:类似版本号,但使用时间戳作为版本标识。 #### 七、事务...
- **隐式锁(implicit lock):** 当事务操作未显式加锁的数据时,InnoDB会通过隐式锁来实现锁的功能,避免数据不一致。 ### InnoDB多版本 多版本并发控制(MVCC)是InnoDB实现非锁定读取的关键机制。在MVCC中,...
- **悲观锁**:在读取数据时就锁定资源,防止其他事务修改,直至事务结束释放锁。Hibernate通过`@Lock`注解配合`LockModeType`实现悲观锁。 **5. 事务的回滚规则** - 任何未捕获的`HibernateException`或`JDBC...
- **提交事务**:使用`COMMIT TRANSACTION`表示事务完成,数据被正式保存。 - **回滚事务**:使用`ROLLBACK TRANSACTION`取消所有事务中的更改,回到事务开始前的状态。 - **保存点**:使用`SAVE TRANSACTION`...
总结来说,MySQL事务和锁的原理是保证数据完整性的重要机制。通过合理地使用事务来确保操作的原子性和一致性,并通过锁机制来实现事务的隔离性。理解这些原理对于数据库开发和维护是非常重要的,能够帮助我们编写出...
- **定义**:意向锁用于表示事务有意向锁定整个表或某个数据集。 - **意向共享锁(IS)**:表示事务想要获取表上的共享锁。 - **意向排他锁(IX)**:表示事务想要获取表上的排他锁。 - **共享意向排他锁(SIX)...
- **更新丢失 (Lost Update):** 当两个事务尝试同时更新同一行数据时,如果后一个事务由于某种原因(如异常、错误等)而未能成功提交,那么前一个事务所做的更新可能会被覆盖或丢失,导致数据不一致。 - **脏读 ...
锁是一种并发控制机制,用来防止多个事务同时访问同一资源而导致的数据不一致问题。 **3.2 引入锁的原因** 由于数据库中的并发操作可能导致数据不一致或丢失更新等问题,因此引入锁机制来保证数据的一致性和准确性...
- **排他锁(Exclusive Locks)**:允许一个事务读取和写入数据项,其他事务无法获取任何类型的锁。 #### 六、应用场景及目标 - **数据库管理员和开发人员**:通过学习事务和锁原理,可以更高效地设计数据库结构,...
在锁方面,InnoDB支持多种锁类型,包括事务锁(Lock)、页面锁(Latch)和互斥锁(Mutex)。事务锁主要用于锁定用户记录或表,其实现复杂,功能多样,可以大量和长时间地持有资源。页面锁相对简单,主要锁定资源是页...