一:mysql事务
1.需求
在示例数据库(yiibaidb)中添加新的销售订单的示例。
- 从
orders
表中查询最新的销售订单编号,并使用下一个销售订单编号作为新的销售订单编号。 - 在指定客户的
orders
表中插入新的销售订单。 - 将新的销售订单项目插入
orderdetails
表中。 - 从
orders
表和orderdetails
中获取数据以确认更改。
如果由于数据库故障而导致上述一个或多个步骤失败,那么数据会发生什么? 如果将订单项添加到orderdetails
表中的步骤失败,系统中将会有空的销售订单(只有订单号,不知道这个订单卖了什么)。
2.介绍
要启动事务,请使用START TRANSACTION
语句。要撤消MySQL语句执行,请使用ROLLBACK
语句。
请注意,有一些SQL语句,主要是数据定义语句,不能在事务中使用以下语句:
要将更改写入事务中的数据库,请使用COMMIT
语句。要注意的是,默认情况下,MySQL自动提交对数据库的更改。
要强制MySQL不会自动提交更改,请使用以下语句:
3.需求的步骤
- 使用START TRANSACTION语句启动事务。
- 从
orders
表中获取最新的销售订单编号,并使用下一个销售订单编号作为新的销售订单编号。 - 在指定
orders
表中插入新的销售订单。 - 将新的销售订单项目插入
orderdetails
表中。 - 使用
COMMIT
语句提交更改。 - 从
orders
表和orderdetails
表中获取数据以确认更改。
4.sql
1 -- start a new transaction 2 start transaction; 3 4 -- get latest order number 5 select @orderNumber := max(orderNUmber) 6 from orders; 7 -- set new order number 8 set @orderNumber = @orderNumber + 1; 9 10 -- insert a new order for customer 145 11 insert into orders(orderNumber, 12 orderDate, 13 requiredDate, 14 shippedDate, 15 status, 16 customerNumber) 17 values(@orderNumber, 18 now(), 19 date_add(now(), INTERVAL 5 DAY), 20 date_add(now(), INTERVAL 2 DAY), 21 'In Process', 22 145); 23 -- insert 2 order line items 24 insert into orderdetails(orderNumber, 25 productCode, 26 quantityOrdered, 27 priceEach, 28 orderLineNumber) 29 values(@orderNumber,'S18_1749', 30, '136', 1), 30 (@orderNumber,'S18_2248', 50, '55.09', 2); 31 -- commit changes 32 commit; 33 34 -- get the new inserted order 35 select * from orders a 36 inner join orderdetails b on a.ordernumber = b.ordernumber 37 where a.ordernumber = @ordernumber;
5.效果
二:表锁定
1.介绍
使用MySQL锁来协调会话之间的表访问。
MySQL允许客户端会话明确获取表锁,以防止其他会话在特定时间段内访问表。客户端会话只能为自己获取或释放表锁。它不能获取或释放其他会话的表锁。
2.准备数据
3.lock与unlock语法
lock:
可将表的名称放在LOCK TABLES
关键字后面,后跟一个锁类型。 MySQL提供两种锁类型:READ
和WRITE
。 我们将在下一节详细介绍这两种锁类型。
unlock:
这个是要释放表的锁。
4.read类型
功能:
- 同时可以通过多个会话获取表的
READ
锁。此外,其他会话可以从表中读取数据,而无需获取锁定。 - 持有
READ
锁的会话只能从表中读取数据,但不能写入。此外,其他会话在释放READ
锁之前无法将数据写入表中。来自另一个会话的写操作将被放入等待状态,直到释放READ
锁。 - 如果会话正常或异常终止,MySQL将会隐式释放所有锁。这也与
WRITE
锁相关。
示例:
A:获取connection_id
B:插入一行数据
INSERT INTO tbl(col) VALUES(10);
C:获取锁,并添加数据
LOCK TABLE tbl READ;
INSERT INTO tbl(col) VALUES(11);
会报错,因为这个时候不可以添加数据。
D:打开另一个会话,查看Id
E:插入数据
F:查看详细 信息
G:返回第一个会话,释放read锁
5.write类型
功能:
- 只有拥有表锁定的会话才能从表读取和写入数据。
- 在释放
WRITE
锁之前,其他会话不能从表中读写。
示例:
A:获取锁,并插入数据
这时,去其他会话进行查询数据:
不能读写。
B:回到会话一释放锁
UNLOCK TABLES;
C:进入会话二进行操作
这时可以进行读写操作,刚才被锁住的查询可以继续执行。