2015-06-07 8 views
5

Önceki sorgularda otomatik olarak START TRANSACTIONCOMMIT olduğunu fark ettim. Bu nedenle ve tüm işlemin sonundan önce çağrılan birkaç saklı yordamım olduğu için, bir START TRANSACTION içeride olup olmadığımı kontrol etmem gerekiyor. Kılavuzun okunması Otomatik görüşmenin, START TRANSACTION içinde yanlış olarak ayarlandığını anladım, ancak böyle görünmüyor. I = KAPALI özdevinimli edilecek ikinci beklenen süreMySQL - START TRANSACTION etkin olduğunda nasıl kontrol edilir

CREATE DEFINER=`root`@`localhost` PROCEDURE `test_transaction`() 
BEGIN 

show session variables like 'autocommit'; 

start transaction; 

show session variables like 'autocommit'; 

COMMIT; 

show session variables like 'autocommit'; 

END 

Fakat her show session variables like 'autocommit'; gösteri özdevinimli = AÇIK: Ben aşağıdaki yordamı yazdım.

START TRANSACTION'un içinde olup olmadığımı nasıl kontrol edebilirim?

START TRANSACTION gerektiren bir yordamıma sahip olduğum için bu denetimi gerçekleştirmem gerekiyor, daha sonra START TRANSACTION'a gereksinim duyan yordamı2 çağırır. Ama benim de prosedür 2'yi çağırmak için gereken farklı bir prosedür farklı bir prosedürü olduğunu varsayalım ama bu durumda farklı_prosedürü START TRANSACTION'u kullanmaz. Bu senaryoda, START TRANSACTION'un başlatılıp başlatılmadığını kontrol etmek için prosedür 2'ye ihtiyacım var. Umarım bu yeterlidir.

Teşekkür https://dev.mysql.com/doc/refman/5.5/en/implicit-commit.html itibaren

cevap

1

:

İşlemleri iç içe olamaz. Bu, bir START TRANSACTION deyimi veya eşanlamlı bir deyim yayınladığınızda geçerli işlem için gerçekleştirilen örtülü taahhüdün bir sonucudur.

Sorunun START TRANSACTION; yerine SET autocommit=0; kullanılarak çözülebileceğinden şüpheleniyorum. Eğer autocommit zaten 0 ise, hiçbir etkisi olmaz.

Ayrıca bkz Does setting autocommit=0 within a transaction do anything?

+0

Teşekkür kullanabilirsiniz, bu bir çözüm olabilir, ama çirkin. "Start transaction" içinde olup olmadığınızı kontrol etmek için temiz bir yol olması gerektiğine inanıyorum –

+0

@Stefano Giacone 'SELECT @@ autocommit' denediniz mi? –

+0

Evet, aynı. SET autocommit = 0; çözüm gerçekten korkunç, eğer mümkünse daha iyi bir tane tercih ederim ... –

5

Yalnızca bir işlem içinde ortaya çıkabilir bir hata sömürecek bir işlev oluşturabilirsiniz:

DELIMITER // 
CREATE FUNCTION `is_in_transaction`() RETURNS int(11) 
BEGIN 
    DECLARE oldIsolation TEXT DEFAULT @@TX_ISOLATION; 
    DECLARE EXIT HANDLER FOR 1568 BEGIN 
     -- error 1568 will only be thrown within a transaction 
     RETURN 1; 
    END; 
    -- will throw an error if we are within a transaction 
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; 
    -- no error was thrown - we are not within a transaction 
    SET TX_ISOLATION = oldIsolation; 
    RETURN 0; 
END// 
DELIMITER ; 

Testi fonksiyonu:

set @within_transaction := null; 
set @out_of_transaction := null; 

begin; 
    set @within_transaction := is_in_transaction(); 
commit; 

set @out_of_transaction := is_in_transaction(); 

select @within_transaction, @out_of_transaction; 

Sonucu :

@within_transaction | @out_of_transaction 
--------------------|-------------------- 
        1 |     0 

mariadb ile @@in_transaction

İlgili konular