>The application I have in mind to work on will require transaction support and I wanted to evaluate these questions
> before I started working with phpPeanuts.
Of course. I hope i can answer them.
>How difficult would it be to enable transaction support on mySql table types that support transactions?
>or, How much work would it take for me to modify the phpPeanuts classes to enable transaction support?
As usual, this depends on your requirements. If it is OK to you to have 1 http request = 1 transaction, it may be quite simple: define tables that support transactions, adapt classes ObjectSaveAction, ObjectDeletAction and ObjectDeleteMarkedAction to first initiate the transaction if required, and to commit it at the end. Maybe we should also adapt QueryHandler to SELECT FOR UPDATE if a transaction is pending. To inform it a transaction is pending, we could use the object that is in the global $site. This object has a field $dbc. In this field there is an object of class DatabaseConnection. This seems the proper place to remember the pending transaction. Most relational databases don't support nested transactions, so let's forget about that for now.
There are some problems with this aproach:
1. The default versions of ObjectSaveAction and ObjectDeletAction do only act on a single object. By default this corresponds to one row in the database. In other words, the transactions will usually only affect one row. Not very usefull to have transactions for that. But OK, ObjectDeleteMarkedAction DOES affect multiple objects, and therfore multiple rows. Furthermore, phpPeanuts is a framework. You are expected to override the save() and delete() methods on your domain model classes if required. As soon as saving or deleting one object affects other objects, or more then one row, you DO need transactions. And of course you can add more custom Action classes, that do complicated things, they may require transactions too.
2. Transaction integrity only holds for everything that happens during the HTTP request that is handled by the Action. It is seldomly mentioned, but in the eyes of the end user a transaction should start as soon as the user starts editing an object. When he finally hits 'submit', the data from his form should not overwrite newer data that was submitted by another user while he was editing. To get this done requires that every form holds a version number that is checked against the version number of the object, that was retrieved FOR UPDATE from the database. That was the simple part. It can be added quite easily to your own DbObject subclass that you use as a superclass for all your domain model classes. The hard part is: what do you do if the version number from the form is different from the one in the database? You can roll back the transaction, but can you roll back the edit and throw away the contents of the users form? Maybe, maybe not. Or maybe that depends on the class of object? Or on the class of the Form (the Action)? Same for when your database does optimistic locking en tells you your transaction was rolled back. I cant's answer those questions for you. Maybe you can ask your users.
3. Even if you solved 2, the whole thing is still only doing record level locking as you database supports it, that is for short term transactions. Some applications, like a content manangement system, may require long term transaction integrity. You will have to implement that yourself. Others, like certain Web Services, may require distributed transactions, maybe even with weak transactions that do not fully guarantee integrity but instead,
Post Edited (09-23-04 21:55)
Add a Reply
Loading form, please wait
The website will not send you an e-mail when a reply is added to this topic
> before I started working with phpPeanuts.
Of course. I hope i can answer them.
>How difficult would it be to enable transaction support on mySql table types that support transactions?
>or, How much work would it take for me to modify the phpPeanuts classes to enable transaction support?
As usual, this depends on your requirements. If it is OK to you to have 1 http request = 1 transaction, it may be quite simple: define tables that support transactions, adapt classes ObjectSaveAction, ObjectDeletAction and ObjectDeleteMarkedAction to first initiate the transaction if required, and to commit it at the end. Maybe we should also adapt QueryHandler to SELECT FOR UPDATE if a transaction is pending. To inform it a transaction is pending, we could use the object that is in the global $site. This object has a field $dbc. In this field there is an object of class DatabaseConnection. This seems the proper place to remember the pending transaction. Most relational databases don't support nested transactions, so let's forget about that for now.
There are some problems with this aproach:
1. The default versions of ObjectSaveAction and ObjectDeletAction do only act on a single object. By default this corresponds to one row in the database. In other words, the transactions will usually only affect one row. Not very usefull to have transactions for that. But OK, ObjectDeleteMarkedAction DOES affect multiple objects, and therfore multiple rows. Furthermore, phpPeanuts is a framework. You are expected to override the save() and delete() methods on your domain model classes if required. As soon as saving or deleting one object affects other objects, or more then one row, you DO need transactions. And of course you can add more custom Action classes, that do complicated things, they may require transactions too.
2. Transaction integrity only holds for everything that happens during the HTTP request that is handled by the Action. It is seldomly mentioned, but in the eyes of the end user a transaction should start as soon as the user starts editing an object. When he finally hits 'submit', the data from his form should not overwrite newer data that was submitted by another user while he was editing. To get this done requires that every form holds a version number that is checked against the version number of the object, that was retrieved FOR UPDATE from the database. That was the simple part. It can be added quite easily to your own DbObject subclass that you use as a superclass for all your domain model classes. The hard part is: what do you do if the version number from the form is different from the one in the database? You can roll back the transaction, but can you roll back the edit and throw away the contents of the users form? Maybe, maybe not. Or maybe that depends on the class of object? Or on the class of the Form (the Action)? Same for when your database does optimistic locking en tells you your transaction was rolled back. I cant's answer those questions for you. Maybe you can ask your users.
3. Even if you solved 2, the whole thing is still only doing record level locking as you database supports it, that is for short term transactions. Some applications, like a content manangement system, may require long term transaction integrity. You will have to implement that yourself. Others, like certain Web Services, may require distributed transactions, maybe even with weak transactions that do not fully guarantee integrity but instead,
Post Edited (09-23-04 21:55)