一、事务支持
MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关。
1. MyISAM 不支持事务,用于只读程序提高性能;
2. InnoDB 支持ACID事务,行级锁、并发;
3. Berkeley DB 支持事务。
二、隔离级别
隔离级别决定了一个session中的事务可能对另一个session的影响、并发session对数据库的操作、一个session中所见数据的一致性。
ANSI标准定义了4个隔离级别,MySQL的InnoDB都支持:
1. READ-UNCOMMITTED:最低级别的隔离,通常又称为dirty read,它允许一个事务读取还没commit的数据,这样可能会提高性能,但是dirty read可能不是我们想要的。
2. READ-COMMITTED:在一个事务中只允许已经commit的记录可见,如果session中select还在查询中,另一session此时insert一条记录,则新添加的数据不可见。
3. REPEATABLE-READ:在一个事务开始后,其他session对数据库的修改在本事务中不可见,直到本事务commit或rollback。在一个事务中重复select的结果一样,除非本事务中update数据库。
4. SERIALIZABLE:最高级别的隔离,只允许事务串行执行。为了达到此目的,数据库会锁住每行已经读取的记录,其他session不能修改数据直到前一事务结束,事务commit或取消时才释放锁。
MySQL 隔离级别设置:
# 设置 SET TRANSACTION ISOLATION LEVEL {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE} # 查看 SELECT @@tx_isolation
MySQL默认的隔离级别是REPEATABLE READ,在设置隔离级别为READ UNCOMMITTED或SERIALIZABLE时要小心,READ UNCOMMITTED会导致数据完整性的严重问题,而SERIALIZABLE会导致性能问题并增加死锁的机率。
三、悲观锁及乐观锁
悲观锁:在读取数据时锁住那几行,其他对这几行的更新需要等到悲观锁结束时才能继续;
乐观所:读取数据时不锁,更新时检查是否数据已经被更新过,如果是则取消当前更新。
一般在悲观锁的等待时间过长而不能接受时我们才会选择乐观锁 。两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。
悲观锁示例:
CREATE PROCEDURE tfer_funds (from_account INT, to_account INT,tfer_amount NUMERIC(10,2), OUT status INT, OUT message VARCHAR(30)) BEGIN DECLARE from_account_balance NUMERIC(10,2); START TRANSACTION; SELECT balance INTO from_account_balance FROM account_balance WHERE account_id=from_account FOR UPDATE; IF from_account_balance>=tfer_amount THEN UPDATE account_balance SET balance=balance-tfer_amount WHERE account_id=from_account; UPDATE account_balance SET balance=balance+tfer_amount WHERE account_id=to_account; COMMIT; SET status=0; SET message='OK'; ELSE ROLLBACK; SET status=-1; SET message='Insufficient funds'; END IF; END;
乐观锁示例:
CREATE PROCEDURE tfer_funds (from_account INT, to_account INT, tfer_amount NUMERIC(10,2), OUT status INT, OUT message VARCHAR(30) ) BEGIN DECLARE from_account_balance NUMERIC(8,2); DECLARE from_account_balance2 NUMERIC(8,2); DECLARE from_account_timestamp1 TIMESTAMP; DECLARE from_account_timestamp2 TIMESTAMP; SELECT account_timestamp,balance INTO from_account_timestamp1,from_account_balance FROM account_balance WHERE account_id=from_account; IF (from_account_balance>=tfer_amount) THEN -- Here we perform some long running validation that -- might take a few minutes */ CALL long_running_validation(from_account); START TRANSACTION; -- Make sure the account row has not been updated since -- our initial check SELECT account_timestamp, balance INTO from_account_timestamp2,from_account_balance2 FROM account_balance WHERE account_id=from_account FOR UPDATE; IF (from_account_timestamp1 <> from_account_timestamp2 OR from_account_balance <> from_account_balance2) THEN ROLLBACK; SET status=-1; SET message=CONCAT("Transaction cancelled due to concurrent update", " of account" ,from_account); ELSE UPDATE account_balance SET balance=balance-tfer_amount WHERE account_id=from_account; UPDATE account_balance SET balance=balance+tfer_amount WHERE account_id=to_account; COMMIT; SET status=0; SET message="OK"; END IF; ELSE ROLLBACK; SET status=-1; SET message="Insufficient funds"; END IF; END$$
相关推荐
36谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?
锁可以分为乐观锁和悲观锁两种,悲观锁又可以分为读锁和写锁两种。读锁是一种共享锁,允许多个读操作同时进行;写锁是一种排它锁,阻断其他写锁和读锁。 锁分类 锁可以从性能上分为乐观锁和悲观锁,从对数据库操作...
锁可以分为乐观锁和悲观锁。乐观锁是通过版本对比来实现的,悲观锁是通过加锁来实现的。悲观锁可以分为表锁和行锁,表锁是对整个表加锁,行锁是对某一行数据加锁。悲观锁还可以分为读锁和写锁,读锁是共享锁,写锁是...
锁可以分为乐观锁和悲观锁两种,从对数据库操作的类型分,分为读锁和写锁,从对数据操作的粒度分,分为表锁和行锁。读锁是共享锁,允许多个读操作可以同时进行,而写锁是排它锁,当前写操作没有完成前,它会阻断其他...
乐观锁和悲观锁式并发控制主要采用的技术手段 悲观锁 在关系数据库管理系统中,悲观并发控制(悲观锁,PCC)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作的每...
本文将详细阐述MySQL中的锁机制以及事务的四种隔离级别,以帮助读者更好地理解和应用这些关键概念。 一、锁的概念与分类 1.1 锁的定义 锁是一种用于控制多进程或线程对共享资源访问的同步机制。在数据库中,它...
在本文中,我们将详细介绍 Hibernate 实现悲观锁和乐观锁的代码实现,并讨论 Hibernate 的隔离机制和锁机制。 Hibernate 的隔离机制 Hibernate 的隔离机制是基于数据库的事务隔离级别的。 Hibernate 提供了四种...
1. **乐观锁与悲观锁**:乐观锁假设很少发生冲突,所以在读取数据时不加锁,而在写回数据时检查是否发生冲突。而悲观锁则相反,它在读取数据时立即加锁,防止其他事务修改数据。 2. **读锁(共享锁)与写锁(排他锁...
4. 从锁的态度分类,有悲观锁和乐观锁。悲观锁假定并发操作会导致冲突,所以在数据读取时立即加锁;乐观锁则假设不会发生冲突,仅在更新数据时检查是否发生冲突。 在实际应用中,根据业务需求和性能考虑,开发人员...
什么是乐观锁和悲观锁? 乐观锁和悲观锁的区别? 乐观锁和悲观锁的使用场景? 什么是死锁? 解决死锁的机制有哪些? 发生死锁的场景有哪些? 什么是事务? 事务的特性与适用场景? 事务的隔离级别与适用场景?
- 通常通过版本号或时间戳实现,MySQL 中没有内置的乐观锁,但可以在应用层面实现。 六、减少锁冲突和死锁的措施 1. 优化事务处理逻辑,避免长时间持有锁。 2. 使用短事务,减少锁的持有时间。 3. 适当使用读未...
在实际开发中,Java程序员需要根据业务需求和并发场景选择合适的锁策略,并合理设置事务隔离级别,以确保数据一致性并避免死锁。 总结来说,“MySQL与Java锁的学习”涵盖了数据库锁机制和Java中与数据库交互的并发...
在数据库系统中,为了保证数据的一致性和完整性,有多种并发控制策略,其中包括乐观锁和悲观锁。这两种锁机制主要用于解决事务在并发环境中的数据冲突问题。 乐观锁是一种假设事务在执行过程中不会发生冲突的策略。...
MySQL 中的事务隔离级别包括 Read uncommitted、Read committed、Repeatable read 和Serializable 四个级别,用于控制事务之间的并发访问。 性能优化 14. 如何优化 MySQL 的性能?可以使用合适的索引、避免全表...
- 按加锁的方式分为:乐观锁和悲观锁。 4. 行锁的原理与算法: 行锁是指只对数据库表中某一行记录加锁,MySQL中InnoDB存储引擎支持行锁,其目的是减少锁冲突,提高并发性。行锁的算法通常有: - 记录锁(Record ...