事务是一个在数据库系统中执行的一系列操作的集合,这些操作被看作是一个不可分割的工作单位。事务的主要目的是确保数据的完整性和一致性。
在事务中,所有操作要么全部成功完成,要么全部不发生。也就是说,如果事务中的任何部分失败,那么整个事务就会被回滚到开始之前的状态,就像这些操作从未发生过一样。这确保了数据的一致性,防止了因部分操作成功而另一部分失败导致的数据不一致问题。
例如,在银行转账过程中,从一个账户扣除金额并添加到另一个账户的操作就应该在一个事务中进行。如果扣款成功但加款失败,事务会回滚,确保不会出现一个账户钱少了而另一个账户钱没多的情况。
从事务的角度来说,会有一下步骤:
默认情况下,MySQL的事务是自动提交的,这意味着每执行完一条DML语句(如INSERT、UPDATE、DELETE等),MySQL会立即隐式地提交事务。但在需要保证事务完整性的场景下,通常需要手动控制事务的开始和结束,以确保数据的一致性和完整性。
数据准备:
drop table if exists account;
create table account(
id int primary key AUTO_INCREMENT comment 'ID',
name varchar(10) comment '姓名',
money double(10,2) comment '余额'
) comment '账户表';
insert into account(name, money) VALUES ('张三',2000), ('李四',2000);
-- 1. 查询张三余额
select * from account where name = '张三';
-- 2. 张三的余额减少1000
update account set money = money - 1000 where name = '张三';
-- 3. 李四的余额增加1000
update account set money = money + 1000 where name = '李四';
三条sql同时执行:
刷新数据库,表数据发生改变:
-- 1. 查询张三余额
select * from account where name = '张三';
-- 2. 张三的余额减少1000
update account set money = money - 1000 where name = '张三';
我是异常sql语句...
-- 3. 李四的余额增加1000
update account set money = money + 1000 where name = '李四';
方式一:通过设置autocommit的值来自动或者手动指定事务
autocommit = 1 表示自动提交,autocommit = 0 表示手动提交
MySQL默认情况下是autocommit = 1 自动提交
SELECT @@autocommit ;
SET @@autocommit = 0 ;
COMMIT;
ROLLBACK;
示例:
先把事务提交方式改为手动提交
此时执行语句后,刷新数据库,数据不会发生变化
只有手动提交事务才能更新数据
如果此时出现了异常,需要回滚事务,撤销之前的事务操作,则需要执行rollback操作
此时数据没更新是因为autocommit = 0 手动提交,现还处于一个事物步骤内
只是发生了事物操作异常,现在就需要对事物进行回滚
执行rollback语句后,事务操作完成,数据表里面的数据不会发生变化,保证数据的一致性和完整性
方式二:通过设置 START TRANSACTION 或 BEGIN 来执行事务
START TRANSACTION 或 BEGIN ;
COMMIT;
ROLLBACK;
示例:
因为设有start transaction,即使现在autocommit = 1 表示自动提交数据库的数据也不会发生变化
只有手动commit提交数据库才会发生变化,现在有事务异常需要rollback回滚事务
如果正常执行完毕, 则提交事务
事务的四大特性,简称ACID,是数据库系统中确保数据完整性和一致性的核心原则。
总的来说,ACID特性是数据库系统提供的一种机制,用于管理和控制对数据库的修改,以确保数据的准确性和可靠性,尤其是在并发环境下。通过遵循这些特性,数据库系统能够保证事务的执行不会导致数据的不一致或错误。
在MySQL中,当多个事务同时执行时,可能会遇到以下几种并发事务问题:
为了解决这些问题,MySQL提供了不同的事务隔离级别和锁机制。在选择合适的事务隔离级别时,需要权衡并发性和数据一致性之间的关系。在某些情况下,可能需要使用显式锁定或者应用程序级别的逻辑来进一步控制并发访问和修改数据。
为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别。
隔离级别 |
脏读 |
不可重复读 |
幻读 |
Read uncommitted |
√ |
√ |
√ |
Read committed |
× |
√ |
√ |
Repeatable Read(默认) |
× |
× |
√ |
Serializable |
× |
× |
× |
注意:事务隔离级别越高,数据越安全,但是性能越低。
SELECT @@TRANSACTION_ISOLATION;
返回一个字符串值,表示当前会话的事务隔离级别。可能的返回值包括:
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
例如,要将当前会话的事务隔离级别设置为READ COMMITTED,可以使用以下命令:
sql
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
或者,要全局地设置事务隔离级别为SERIALIZABLE,可以使用以下命令:
sql
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
注意:但是请注意,更改全局事务隔离级别可能会影响整个系统的性能和并发性,因此在进行此类更改时需要谨慎考虑。通常情况下,建议根据具体的应用场景和需求来选择合适的事务隔离级别。