Here's a code sample which can raise db lock wait exception:

def create_port_postcommit(self, context):

port_id = ...
with session.begin(subtransactions=True):
    try:
        binding = (session.query(models.PortBinding).
                  filter(models.PortBinding.port_id.startswith(port_id)).
                  one())
        # Here I modify some attributes if port binding is existed
        session.merge(query)
    except exc.NoResultFound:
        # Here I insert new port binding record to initialize some attributes
    except ...
        LOG.error("error happened")

The exception is as follows:
2014-06-25 10:05:17.195 9915 ERROR neutron.plugins.ml2.managers 
[req-961680da-ce69-43c6-974c-57132def411d None] Mechanism driver 'hello' failed 
in create_port_postcommit
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers Traceback (most 
recent call last):
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File 
"/usr/lib/python2.6/site-packages/neutron/plugins/ml2/managers.py", line 158, 
in _call_on_drivers
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     
getattr(driver.obj, method_name)(context)
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File 
"/usr/lib/python2.6/site-packages/neutron/plugins/ml2/drivers/mech_hello.py", 
line 95, in create_port_postcommit
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     {'port_id': 
port_id})
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File 
"/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py",
 line 402, in __exit__
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     
self.commit()
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File 
"/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py",
 line 314, in commit
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     
self._prepare_impl()
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers   File 
"/usr/lib64/python2.6/site-packages/SQLAlchemy-0.7.8-py2.6-linux-x86_64.egg/sqlalchemy/orm/session.py",
 line 298, in _prepare_impl
2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers     
self.session.flush()

...

2014-06-25 10:05:17.195 9915 TRACE neutron.plugins.ml2.managers 
OperationalError: (OperationalError) (1205, 'Lock wait timeout exceeded; try 
restarting transaction') 'INSERT INTO ml2_port_bindings (port_id, host, 
vnic_type, profile, vif_type, vif_details, driver, segment) VALUES (%s, %s, %s, 
%s, %s, %s, %s, %s)' (...)

It seems that the transaction in the postcommit cannot be committed.

Thanks a lot,
Li Ma

----- Original Message -----
From: "Li Ma" <[email protected]>
To: "OpenStack Development Mailing List (not for usage questions)" 
<[email protected]>
Sent: 星期三, 2014年 6 月 25日 下午 6:21:10
Subject: Re: [openstack-dev] [Neutron ML2] Potential DB lock when developing 
new mechanism driver

Hi Kevin,

Thanks for your reply. Actually, it is not that straightforward.
Even if postcommit is outside the 'with' statement, the transaction is not 
'truly' committed immediately. Because when I put my db code (reading and 
writing ml2-related tables) in postcommit, db lock wait exception is still 
thrown.

Li Ma

----- Original Message -----
From: "Kevin Benton" <[email protected]>
To: "OpenStack Development Mailing List (not for usage questions)" 
<[email protected]>
Sent: 星期三, 2014年 6 月 25日 下午 4:59:26
Subject: Re: [openstack-dev] [Neutron ML2] Potential DB lock when developing 
new mechanism driver



The post_commit methods occur outside of the transactions. You should be able 
to perform the necessary database calls there. 


If you look at the code snippet in the email you provided, you can see that the 
'try' block surrounding the postcommit method is at the same indentation-level 
as the 'with' statement for the transaction so it will be closed at that point. 


Cheers, 
Kevin Benton 


-- 
Kevin Benton 



On Tue, Jun 24, 2014 at 8:33 PM, Li Ma < [email protected] > wrote: 


Hi all, 

I'm developing a new mechanism driver. I'd like to access ml2-related tables in 
create_port_precommit and create_port_postcommit. However I find it hard to do 
that because the two functions are both inside an existed database transaction 
defined in create_port function of ml2/plugin.py. 

The related code is as follows: 

def create_port(self, context, port): 
... 
session = context.session 
with session.begin(subtransactions=True): 
... 
self.mechanism_manager.create_port_precommit(mech_context) 
try: 
self.mechanism_manager.create_port_postcommit(mech_context) 
... 
... 
return result 

As a result, I need to carefully deal with the database nested transaction 
issue to prevent from db lock when I develop my own mechanism driver. Right 
now, I'm trying to get the idea behind the scene. Is it possible to refactor it 
in order to make precommit and postcommit out of the db transaction? I think it 
is perfect for those who develop mechanism driver and do not know well about 
the functioning context of the whole ML2 plugin. 

Thanks, 
Li Ma 

_______________________________________________ 
OpenStack-dev mailing list 
[email protected] 
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev 




-- 

Kevin Benton 
_______________________________________________
OpenStack-dev mailing list
[email protected]
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev

_______________________________________________
OpenStack-dev mailing list
[email protected]
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev

Reply via email to