Transaction.hx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Copyright (C)2005-2012 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. package sys.db;
  23. class Transaction {
  24. public static function isDeadlock(e : Dynamic) {
  25. return Std.is(e,String) && ~/try restarting transaction/.match(e);
  26. }
  27. private static function runMainLoop(mainFun,logError,count) {
  28. try {
  29. mainFun();
  30. } catch( e : Dynamic ) {
  31. if( count > 0 && isDeadlock(e) ) {
  32. Manager.cleanup();
  33. Manager.cnx.rollback(); // should be already done, but in case...
  34. Manager.cnx.startTransaction();
  35. runMainLoop(mainFun,logError,count-1);
  36. return;
  37. }
  38. if( logError == null ) {
  39. Manager.cnx.rollback();
  40. #if neko
  41. neko.Lib.rethrow(e);
  42. #else
  43. throw e;
  44. #end
  45. }
  46. logError(e); // should ROLLBACK if needed
  47. }
  48. }
  49. public static function main( cnx, mainFun : Void -> Void, ?logError : Dynamic -> Void ) {
  50. Manager.initialize();
  51. Manager.cnx = cnx;
  52. Manager.cnx.startTransaction();
  53. runMainLoop(mainFun,logError,3);
  54. try {
  55. Manager.cnx.commit();
  56. } catch( e : String ) {
  57. // sqlite can have errors on commit
  58. if( ~/Database is busy/.match(e) )
  59. logError(e);
  60. }
  61. Manager.cnx.close();
  62. Manager.cnx = null;
  63. Manager.cleanup();
  64. }
  65. }