The cause of this issue is our server changes the shard of all models in 
before filter for each request based on if the coming request method is 
"GET" or non-"GET"(POST, PATCH, PUT)

If it's a "GET" request, we do
ALL_MODELS.each { |model| model.dataset = model.dataset.server(:slave) }

otherwise, we do
ALL_MODELS.each { |model| model.dataset = model.dataset.server(:master) }

The idea behind this is that, we do not want to choose whether to use 
master or slave based on if the query is a "SELECT", instead we want to 
choose slave for "GET" requests, and master for non-"GET" requests.

The problem can be reproduced by the following steps:
1. start the server
2. make as many  "POST" requests as you want, and the the rollback works 
fine
3. make a "GET" request, which would change all the models to point to 
:slave
4. make a "POST" request, which would change all the models back to 
:master, and the rollback starts to fail from now on just as Gabe 
N describes.

If you could let us know why is this causing the problem, if we are doing 
something wrong and if you have any alternative suggestions to approach 
this.

Thanks in advance! 

On Friday, February 21, 2014 12:17:17 PM UTC-8, Jeremy Evans wrote:
>
> On Friday, February 21, 2014 12:04:52 PM UTC-8, [email protected] wrote:
>>
>> I am using Mysql 5.6 with a threaded connection pool with 4.7.0 of 
>> Sequel.  I am noticing that the following simplified snippet fails to 
>> rollback:
>>
>> DB.transaction do
>>   ModelClass.filter(:some_id => var_id).delete
>>   raise Sequel::Rollback
>> end
>>
>> I am seeing that the delete will occur even though a rollback happens.  I 
>> debugged this in mysql log and I am seeing that the delete call is 
>> occurring on a different connection than the transaction call.
>>
>>     23 Query BEGIN
>>
>>    35 Query DELETE FROM `model_class` WHERE (`some_id` = 123)
>>
>>    23 Query ROLLBACK
>>
>> Therefore, the delete goes through.  If I change my code to:
>> DB.transaction do
>>  DB[:model_class].filter(:some_id => var_id).delete
>>  raise Sequel::Rollback
>> end
>>
>> The delete is correctly rolled back and I see in the mysql logs that the 
>> same connection is used.  If I have to use a Sequel Dataset 
>> (DB[:model_class]), I am not able to use convenient model methods like 
>> "save".  Instead I have to use "insert" on the dataset which will not run 
>> all the conveniences of a model save (i.e. after_save callback, etc.).  Is 
>> there any way to continue using the ModelClass instead of a Sequel Dataset? 
>>  I've unsuccessfully tried prepared transactions, DB.synchronize, etc.
>>
>> Also, I see at the bottom of 
>> http://sequel.jeremyevans.net/rdoc/files/doc/transactions_rdoc.html, 
>> find_or_create is called on a model class which has the same problem as my 
>> first example above.
>>
>> Thanks in advance for the help, and please let me know if you have any 
>> questions.
>>
>
> I can't reproduce this:
>
> Your database is stored in DB...
> irb(main):001:0> DB.create_table!(:model_classes, 
> :engine=>'InnoDB'){primary_key :id; String :a}
> I, [2014-02-21T12:11:33.212360 #23063]  INFO -- : (0.000873s) DROP TABLE 
> IF EXISTS `model_classes`
> I, [2014-02-21T12:11:33.214885 #23063]  INFO -- : (0.001996s) CREATE TABLE 
> `model_classes` (`id` integer PRIMARY KEY AUTO_INCREMENT, `a` varchar(255)) 
> ENGINE=InnoDB
> => nil
> irb(main):002:0> DB[:model_classes].insert(:a=>1)
> I, [2014-02-21T12:11:33.217073 #23063]  INFO -- : (0.000762s) INSERT INTO 
> `model_classes` (`a`) VALUES (1)
> => 1
> irb(main):003:0> class ModelClass < Sequel::Model; end
> I, [2014-02-21T12:11:33.220640 #23063]  INFO -- : (0.001565s) DESCRIBE 
> `model_classes`
> => nil
> irb(main):004:0> DB.transaction do
> irb(main):005:1*   ModelClass.filter(:id => 1).delete
> irb(main):006:1>   raise Sequel::Rollback
> irb(main):007:1> end
> I, [2014-02-21T12:11:33.224537 #23063]  INFO -- : (0.000072s) BEGIN
> I, [2014-02-21T12:11:33.225083 #23063]  INFO -- : (0.000270s) DELETE FROM 
> `model_classes` WHERE (`id` = 1)
> I, [2014-02-21T12:11:33.225639 #23063]  INFO -- : (0.000343s) ROLLBACK
> => nil
> irb(main):008:0> ModelClass.all
> I, [2014-02-21T12:11:33.919494 #23063]  INFO -- : (0.000409s) SELECT * 
> FROM `model_classes`
> => [#<ModelClass @values={:id=>1, :a=>"1"}>]
>
> If you aren't using separate threads or sharding, I can't think of a 
> reason why you would be using separate connections for the transaction as 
> opposed to the delete query inside the transaction.  Please post a self 
> contained example showing the problem (similar to the above).
>
> Thanks,
> Jeremy
>

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to