简体   繁体   English

mysql CREATE临时表+ Transaction导致死锁

[英]mysql CREATE temporary table + Transaction causes deadlock

I have the complex query that creates a temporary table that can take 5 seconds to run or more. 我有复杂的查询,创建一个临时表,可能需要5秒钟才能运行或更多。 This seems to be causing a deadlock when running another transaction on similar tables at the same time. 这似乎在同时在类似的表上运行另一个事务时导致死锁。 I cannot reproduce locally, but on production I am able to have it happen 1 time every few days. 我不能在本地复制,但在生产中我能够每隔几天发生一次。 (I logged the mysql errors) (我记录了mysql错误)

The query is pretty complicated (shown at bottom of page); 查询非常复杂(显示在页面底部); but you don't need to understand the logic; 但你不需要理解逻辑; just that it selects from a bunch of tables and joins and can take awhile to run. 只是它从一堆表和连接中选择,可能需要一段时间才能运行。

I also have a transaction that inserts into many of the same tables. 我还有一个插入许多相同表的事务。 I get a mysql error occasionally 1213: Deadlock found when trying to get lock; try restarting transaction. 我偶尔得到一个mysql错误1213: Deadlock found when trying to get lock; try restarting transaction. 1213: Deadlock found when trying to get lock; try restarting transaction.

Here is pseudocode for the transaction 这是交易的伪代码

START TRANSACTION
INSERT INTO phppos_sales
INSERT MANY RECORDS INTO phppos_sales_items
INSERT MANY RECORDS INTO phppos_sales_items_taxes
INSERT MANY RECORDS INTO phppos_sales_payments
END TRANSACTION

How do I go about resolving this deadlock? 我该如何解决这个僵局? I tried changing isolation level to READ UNCOMMITTED but mysql settings wouldn't allow for this; 我尝试将隔离级别更改为READ UNCOMMITTED但是mysql设置不允许这样做; and I need to make this work in a variety of environments where I don't have control of the server. 我需要在我无法控制服务器的各种环境中完成这项工作。

ERROR when changing isolation level: 更改隔离级别时出错:

Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. 无法执行语句:因为BINLOG_FORMAT = STATEMENT而无法写入二进制日志,并且至少有一个表使用仅限于基于行的日志记录的存储引擎。 InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED. 当事务隔离级别为READ COMMITTED或READ UNCOMMITTED时,InnoDB仅限于行记录。

INNODB ENGINE STATUS: INNODB发动机状态:

mysql> SHOW ENGINE INNODB STATUS;
| Type   | Name | Status                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| InnoDB |      | 
=====================================
140520 12:00:17 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 15 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 1766819 1_second, 1766816 sleeps, 167043 10_second, 100947 background, 100945 flush
srv_master_thread log flush and writes: 1776023
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 236559, signal count 288374
Mutex spin waits 546890, rounds 1796579, OS waits 33216
RW-shared spins 205374, rounds 5519210, OS waits 176937
RW-excl spins 5661, rounds 841678, OS waits 23933
Spin rounds per wait: 3.29 mutex, 26.87 RW-shared, 148.68 RW-excl
------------------------
LATEST FOREIGN KEY ERROR
------------------------
140520 11:27:44 Transaction:
TRANSACTION 86D125F, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
15 lock struct(s), heap size 3112, 6 row lock(s), undo log entries 2
MySQL thread id 1910245, OS thread handle 0x7fbf0042e700, query id 56114114 php-pos-web 10.181.16.33 phppoint update
INSERT INTO `phppos_sales_items_taxes` (`sale_id`, `item_id`, `line`, `name`, `percent`, `cumulative`) VALUES (11763, 1115, 3, 'PST', '8.000', '0')
Foreign key constraint fails for table `phppoint_fatpanda`.`phppos_sales_items_taxes`:
,
  CONSTRAINT `phppos_sales_items_taxes_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `phppos_sales_items` (`sale_id`)
Trying to add in child table, in index `PRIMARY` tuple:
DATA TUPLE: 8 fields;
 0: len 4; hex 80002df3; asc   - ;;
 1: len 4; hex 8000045b; asc    [;;
 2: len 4; hex 80000003; asc     ;;
 3: len 3; hex 505354; asc PST;;
 4: len 8; hex 8000000000080000; asc         ;;
 5: len 6; hex 0000086d125f; asc    m _;;
 6: len 7; hex 00000000000000; asc        ;;
 7: len 4; hex 80000000; asc     ;;

But in parent table `phppoint_fatpanda`.`phppos_sales_items`, in index `PRIMARY`,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 11; compact format; info bits 0
 0: len 4; hex 80002df1; asc   - ;;
 1: len 4; hex 8000049a; asc     ;;
 2: len 4; hex 80000001; asc     ;;
 3: len 6; hex 0000086cfd29; asc    l );;
 4: len 7; hex f400000216012c; asc       ,;;
 5: len 0; hex ; asc ;;
 6: len 0; hex ; asc ;;
 7: len 11; hex 8000000000010000000000; asc            ;;
 8: len 11; hex 8000000000100000000000; asc            ;;
 9: len 11; hex 80000000002d0000000000; asc      -     ;;
 10: len 4; hex 80000000; asc     ;;

------------------------
LATEST DETECTED DEADLOCK
------------------------
140520 11:27:44
*** (1) TRANSACTION:
TRANSACTION 86D11A3, ACTIVE 2 sec fetching rows
mysql tables in use 9, locked 9
LOCK WAIT 364 lock struct(s), heap size 47544, 80177 row lock(s)
MySQL thread id 1910243, OS thread handle 0x7fbeb2090700, query id 56113840 10.181.26.42 phppoint Copying to tmp table

CREATE TEMPORARY TABLE phppos_sales_items_temp
        (SELECT phppos_sales.deleted as deleted,phppos_sales.deleted_by as deleted_by, sale_time, date(sale_time) as sale_date, phppos_sales_items.sale_id, comment,payment_type, customer_id, employee_id, 
        phppos_items.item_id, NULL as item_kit_id, supplier_id, quantity_purchased, item_cost_price, item_unit_price, category, 
        discount_percent, (item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100) as subtotal,
        phppos_sales_items.line as line, serialnumber, phppos_sales_items.description as description,
        (item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100)+(item_unit_price*quantity_purchased-item_unit_price*quantity_purchased*discount_percent/100)*(SUM(CASE WHEN cumulative != 1 THEN percent ELSE 0 END)/100) 
        +(((item_unit_price*quantity_purchased-item_unit_price*quanti
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 454941 page no 114 n bits 408 index `location_id` of table `phppoint_fatpanda`.`phppos_sales` trx id 86D11A3 lock mode S waiting
Record lock, heap no 335 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000001; asc     ;;
 1: len 4; hex 80002df3; asc   - ;;

*** (2) TRANSACTION:
TRANSACTION 86D125D, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
23 lock struct(s), heap size 3112, 12 row lock(s), undo log entries 10
MySQL thread id 1910245, OS thread handle 0x7fbf0042e700, query id 56114091 php-pos-web 10.181.16.33 phppoint update

INSERT INTO `phppos_sales_items_taxes` (`sale_id`, `item_id`, `line`, `name`, `percent`, `cumulative`) VALUES (11763, 1178, 2, 'GST', '5.000', '0')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 454941 page no 114 n bits 408 index `location_id` of table `phppoint_fatpanda`.`phppos_sales` trx id 86D125D lock_mode X locks rec but not gap
Record lock, heap no 335 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000001; asc     ;;
 1: len 4; hex 80002df3; asc   - ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 454945 page no 386 n bits 288 index `PRIMARY` of table `phppoint_fatpanda`.`phppos_sales_items_taxes` trx id 86D125D lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

*** WE ROLL BACK TRANSACTION (2)
------------
TRANSACTIONS
------------
Trx id counter 86E47F7
Purge done for trx's n:o < 86E45C0 undo n:o < 0
History list length 1418
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 86E47F6, not started
MySQL thread id 1913171, OS thread handle 0x7fbeb2090700, query id 56205829 10.181.26.42 phppoint
---TRANSACTION 0, not started
MySQL thread id 1913095, OS thread handle 0x7fbf005b4700, query id 56205830 localhost root
SHOW ENGINE INNODB STATUS
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] ,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
3599456 OS file reads, 9300371 OS file writes, 3988632 OS fsyncs
0.27 reads/s, 16384 avg bytes/read, 13.07 writes/s, 7.27 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 84, seg size 86, 55915 merges
merged operations:
 insert 68506, delete mark 4761, delete 38
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 2212699, node heap has 751 buffer(s)
5050.86 hash searches/s, 624.09 non-hash searches/s
---
LOG
---
Log sequence number 184365806376
Log flushed up to   184365806376
Last checkpoint at  184365791715
0 pending log writes, 0 pending chkp writes
2149282 log i/o's done, 3.47 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 1098907648; in additional pool allocated 0
Dictionary memory allocated 62951505
Buffer pool size   65536
Free buffers       1
Database pages     64784
Old database pages 23894
Modified db pages  88
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 4073451, not young 0
0.07 youngs/s, 0.00 non-youngs/s
Pages read 3592230, created 1542046, written 6130789
0.27 reads/s, 18.00 creates/s, 6.40 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 64784, unzip_LRU len: 0
I/O sum[382]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread process no. 15866, id 140457065543424, state: sleeping
Number of rows inserted 77431960, updated 1673031, deleted 160450, read 4825684197
1103.93 inserts/s, 2.53 updates/s, 0.00 deletes/s, 7772.15 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================
 |
+-------

QUERY THIS IS PART OF DEADLOCK: (Along with transaction above) 这是DEADLOCK的一部分:(以及上面的交易)

CREATE temporary TABLE phppos_sales_items_temp 
  (SELECT 
  phppos_sales.deleted                                              AS deleted, 
          phppos_sales.deleted_by                                   AS deleted_by, 
          sale_time, 
          Date(sale_time)                                           AS sale_date, 
          phppos_sales_items.sale_id, 
          comment, 
          payment_type, 
          customer_id, 
          employee_id, 
          phppos_items.item_id, 
          NULL                                                       AS item_kit_id, 
          supplier_id, 
          quantity_purchased, 
          item_cost_price, 
          item_unit_price, 
          category, 
          discount_percent, 
          ( item_unit_price * quantity_purchased - 
            item_unit_price * quantity_purchased * 
            discount_percent / 100 ) AS subtotal, 
          phppos_sales_items.line                                     AS line, 
          serialnumber, 
          phppos_sales_items.description                              AS description, 
          ( item_unit_price * quantity_purchased - 
            item_unit_price * quantity_purchased * 
            discount_percent / 100 ) + ( 
          item_unit_price * quantity_purchased - 
          item_unit_price * quantity_purchased * 
          discount_percent 
          / 100 ) * ( Sum(CASE 
                            WHEN cumulative != 1 THEN percent 
                            ELSE 0 
                          end) / 100 ) + ( ( ( 
          item_unit_price * quantity_purchased 
          - 
          item_unit_price * quantity_purchased 
          * 
          discount_percent / 100 ) * ( 
                                           Sum(CASE 
                                                 WHEN cumulative != 1 THEN 
                                                 percent 
                                                 ELSE 0 
                                               end) / 100 ) + ( 
                                           item_unit_price * quantity_purchased 
                                           - 
                                                            item_unit_price * 
                                                            quantity_purchased 
                                                            * 
                                                            discount_percent / 
                                                            100 
                                                              ) 
                                     ) 
                                           * ( Sum(CASE 
                                                                            WHEN 
                                                   cumulative = 1 THEN percent 
                                                                            ELSE 
                                                   0 
                                                                            end) 
                                             ) 
                                           / 100 ) 
                                                                       AS total, 
          ( item_unit_price * quantity_purchased - 
            item_unit_price * quantity_purchased * 
            discount_percent / 100 ) * ( 
          Sum(CASE 
                WHEN cumulative != 1 THEN percent 
                ELSE 0 
              end) / 100 ) + ( ( ( item_unit_price * quantity_purchased - 
                                   item_unit_price * quantity_purchased * 
                                   discount_percent / 100 ) * ( Sum( 
                                                        CASE 
                                                          WHEN cumulative != 1 
                                                        THEN 
                                                          percent 
                                                          ELSE 0 
                                                        end) / 100 ) + ( 
                                 item_unit_price * quantity_purchased 
                                 - 
                                 item_unit_price * quantity_purchased 
                                 * 
                                 discount_percent / 100 ) ) * ( Sum( 
                                 CASE 
                                 WHEN cumulative = 1 THEN percent 
                                 ELSE 0 
                                 end) ) / 100 )          AS tax, 
          ( item_unit_price * quantity_purchased - 
            item_unit_price * quantity_purchased * 
            discount_percent / 100 ) - ( 
          item_cost_price * quantity_purchased )                      AS profit 
   FROM   phppos_sales_items 
          INNER JOIN phppos_sales 
                  ON phppos_sales_items.sale_id = phppos_sales.sale_id 
          INNER JOIN phppos_items 
                  ON phppos_sales_items.item_id = phppos_items.item_id 
          LEFT OUTER JOIN phppos_suppliers 
                       ON phppos_items.supplier_id = phppos_suppliers.person_id 
          LEFT OUTER JOIN phppos_sales_items_taxes 
                       ON phppos_sales_items.sale_id = 
                          phppos_sales_items_taxes.sale_id 
                          AND phppos_sales_items.item_id = 
                              phppos_sales_items_taxes.item_id 
                          AND phppos_sales_items.line = 
                              phppos_sales_items_taxes.line 
   WHERE  sale_time BETWEEN "2014-04-01 00:00:00" AND "2014-04-30 23:59:59" 
          AND phppos_sales.location_id = '1' 
          AND phppos_sales.store_account_payment = 0 
   GROUP  BY sale_id, 
             item_id, 
             line) 
  UNION ALL 
  (SELECT phppos_sales.deleted 
          AS 
          deleted 
          , 
          phppos_sales.deleted_by 
          AS deleted_by, 
          sale_time, 
          Date(sale_time) 
          AS 
          sale_date, 
          phppos_sales_item_kits.sale_id, 
          comment, 
          payment_type, 
          customer_id, 
          employee_id, 
          NULL 
          AS 
          item_id, 
          phppos_item_kits.item_kit_id, 
          '' 
          AS 
          supplier_id, 
          quantity_purchased, 
          item_kit_cost_price, 
          item_kit_unit_price, 
          category, 
          discount_percent, 
          ( item_kit_unit_price * quantity_purchased - 
            item_kit_unit_price * quantity_purchased * discount_percent / 100 ) 
          AS 
          subtotal, 
          phppos_sales_item_kits.line 
          AS 
          line, 
          '' 
          AS 
          serialnumber, 
          phppos_sales_item_kits.description 
          AS 
          description, 
          ( item_kit_unit_price * quantity_purchased - 
            item_kit_unit_price * quantity_purchased * discount_percent / 100 ) 
          + 
          ( item_kit_unit_price * quantity_purchased - 
            item_kit_unit_price * quantity_purchased * discount_percent / 100 ) *
       ( Sum(  CASE   WHEN  cumulative != 1 THEN percent    ELSE 0  end) / 100 ) 
+ ( ( (  item_kit_unit_price * quantity_purchased  - 
item_kit_unit_price * quantity_purchased * discount_percent / 100 ) *
( Sum(CASE 
WHEN cumulative != 1 THEN percent 
ELSE 0 
      end) 
  / 
  100 ) + ( item_kit_unit_price * quantity_purchased - 
                      item_kit_unit_price * quantity_purchased * 
                      discount_percent / 100 ) ) * ( 
Sum( 
                               CASE 
                                 WHEN cumulative = 1 THEN percent 
                                 ELSE 0 
                               end) ) / 100 )                         AS total, 
( item_kit_unit_price * quantity_purchased - 
  item_kit_unit_price * quantity_purchased * discount_percent / 100 ) * ( Sum( 
CASE 
WHEN cumulative != 1 THEN percent 
ELSE 0 
end) / 100 ) + ( ( ( item_kit_unit_price * quantity_purchased - 
                                        item_kit_unit_price * quantity_purchased 
                                        * 
                                        discount_percent 
                                        / 100 ) * ( Sum( 
                   CASE 
                     WHEN cumulative != 1 THEN percent 
                     ELSE 0 
                   end) / 100 ) + ( 
                                      item_kit_unit_price * quantity_purchased 
                                      - 
                                                 item_kit_unit_price * 
                                                 quantity_purchased 
                                                 * discount_percent / 100 ) ) * 
                 ( 
                                  Sum(CASE 
                                        WHEN cumulative = 1 THEN percent 
                                        ELSE 0 
                                      end) ) / 100 )                  AS tax, 
( item_kit_unit_price * quantity_purchased - 
  item_kit_unit_price * quantity_purchased * discount_percent / 100 ) - ( 
item_kit_cost_price * quantity_purchased )                            AS profit 
 FROM   phppos_sales_item_kits 
        INNER JOIN phppos_sales 
                ON phppos_sales_item_kits.sale_id = phppos_sales.sale_id 
        INNER JOIN phppos_item_kits 
                ON phppos_sales_item_kits.item_kit_id = 
                   phppos_item_kits.item_kit_id 
        LEFT OUTER JOIN phppos_sales_item_kits_taxes 
                     ON phppos_sales_item_kits.sale_id = 
                        phppos_sales_item_kits_taxes.sale_id 
                        AND phppos_sales_item_kits.item_kit_id = 
                            phppos_sales_item_kits_taxes.item_kit_id 
                        AND phppos_sales_item_kits.line = 
                            phppos_sales_item_kits_taxes.line 
 WHERE  sale_time BETWEEN "2014-04-01 00:00:00" AND "2014-04-30 23:59:59" 
        AND phppos_sales.location_id = '1' 
        AND phppos_sales.store_account_payment = 0 
 GROUP  BY sale_id, 
           item_kit_id, 
           line) 
ORDER  BY sale_id, 
          line; 

The Root Cause 根本原因

When you combine a SELECT with a write statement such as INSERT INTO... or CREATE TABLE AS... , then MySQL has to establish a shared lock on the tables involved in the SELECT . SELECT与写入语句(如INSERT INTO...CREATE TABLE AS...组合在一起时,MySQL必须在SELECT涉及的表上建立共享锁

You have another concurrent transaction (2) that holds an exclusive lock on the table phppos_sales , so transaction (1) can't get its S-lock, and transaction (1) waits. 你有另一个并发事务(2),它持有表phppos_sales独占锁 ,因此事务(1)无法获得其S锁,并且事务(1)等待。

Then transaction (2) requests an X-lock on tale phppos_sales_items_taxes . 然后事务(2)在故事phppos_sales_items_taxes上请求X锁定。 But transaction (1) is already in queue to get its S-lock on that table, and transaction (2) must wait behind it in the queue. 但是事务(1)已经在队列中以在该表上获得其S锁,并且事务(2)必须在队列中等待它。

Therefore transaction (2) is waiting on transaction (1), while transaction (1) is waiting on transaction (2). 因此,事务(2)等待事务(1),而事务(1)等待事务(2)。 This is a classic deadlock. 这是一个典型的僵局。

This only happens once every few days because it depends on transaction (2) acquiring its first lock on phppos_sales before transaction (1) starts its SELECT . 这只发生在每隔几天一次,因为它取决于事务(2)在事务(1)启动其SELECT之前获取其对phppos_sales第一次锁定。 Then transaction (2) tries to acquire its second lock on phppos_sales_items_taxes after transaction (1) has its S-lock requests queued. 然后,事务(2)尝试在事务(1)将其S锁定请求排队后获取其对phppos_sales_items_taxes第二次锁定。

In other words, it's a race condition, and those are hard to reproduce. 换句话说,这是一种竞争条件,而且很难再现。

The Remedy 补救措施

If transaction (2) were to request locks on all the tables it needs as an atomic action, then there would be no way for transaction (1) to sneak in between the lock requests. 如果事务(2)要求锁定所有需要作为原子操作的表,那么事务(1)就无法在锁请求之间潜入。

You can achieve this by explicitly using LOCK TABLES : 您可以通过显式使用LOCK TABLES来实现此目的:

START TRANSACTION
LOCK TABLES phppos_sales WRITE, phppos_sales_items WRITE, 
    phppos_sales_items_taxes WRITE, ...other table(s)...
INSERT INTO phppos_sales
INSERT MANY RECORDS INTO phppos_sales_items
INSERT MANY RECORDS INTO phppos_sales_items_taxes
INSERT MANY RECORDS INTO phppos_sales_payments
UNLOCK TABLES;
COMMIT;

This does mean that transaction (1) that does the long-running SELECT has to wait for transaction (2) to finish its INSERT s and unlock its tables. 这确实意味着执行长时间运行的SELECT事务(1)必须等待事务(2)完成其INSERT并解锁其表。

Or else if the SELECT is in progress first, then it means that transaction (2) has to wait for that to finish. 否则,如果SELECT首先进行,则意味着事务(2)必须等待它完成。

A Workaround 解决方法

You could fill your temp table with no lock contention if you avoid using CREATE TABLE... SELECT or INSERT INTO... SELECT . 如果避免使用CREATE TABLE... SELECTINSERT INTO... SELECT则可以在没有锁争用的情况下填充临时表。 That is, fetch the result-set of the SELECT back into your application, and then INSERT those rows into the temp table. 也就是说,取结果集的的SELECT回你的应用程序,然后INSERT这些行插入到临时表。 That way the SELECT won't require any S-locks. 这样SELECT就不需要任何S锁。

You could do the same thing with a cursor in a stored procedure. 您可以使用存储过程中的游标执行相同的操作。

Another Workaround 另一种解决方法

As @BrendanF comments, you can also change your transaction isolation level to READ-COMMITTED instead of the default REPEATABLE-READ. 作为@BrendanF注释,您还可以将事务隔离级别更改为READ-COMMITTED而不是默认的REPEATABLE-READ。 You can either change the default transaction isolation level globally, or you can change isolation level on a session-by-session basis. 您可以全局更改默认事务隔离级别,也可以逐个会话地更改隔离级别。 This changes the semantics of transactions a bit, so you should read about the differences. 这会稍微改变事务的语义,因此您应该阅读有关差异的内容。

But it does eliminate the need for SELECT to do S-locks when reading from tables during those insert/select operations. 但是在插入/选择操作期间从表读取时,它确实消除了SELECT执行S锁的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM