int main(int argc, char *argv[]) { char *pgm = argv[0]; int rc, test_rc, chained;; int rmid = 1; if (argc < 3) { fprintf(stderr, "%s: at least two options must be specified\n", argv[0]); exit (1); } chained = strtol(argv[1], NULL, 0); test_rc = strtol(argv[2], NULL, 0); printf("%s| starting...\n", pgm); printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); assert(TX_PROTOCOL_ERROR == rc); printf("%s| tx_open(): %d\n", pgm, rc = tx_open()); assert(TX_OK == rc); printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); assert(TX_PROTOCOL_ERROR == rc); if (chained) { printf("%s| tx_set_transaction_control(): %d\n", pgm, rc = tx_set_transaction_control(TX_CHAINED)); assert(TX_OK == rc); } printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OK == rc); printf("%s| lixa_monkeyrm_call_ax_reg(%d): %d\n", pgm, rmid, rc = lixa_monkeyrm_call_ax_reg(rmid)); assert(TM_OK == rc); printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); assert(test_rc == rc); if (TX_FAIL != test_rc) { printf("%s| tx_close(): %d\n", pgm, rc = tx_close()); assert(TX_OK == rc); } printf("%s| ...finished\n", pgm); return 0; }
int tpcommit(long flags) { if (flags != 0) { // or Participant TPERROR(TPEPROTO, "flags!=0"); return -1; } // TODO: clean call descriptors, do rollback int rc = tx_commit(); if (rc == TX_OK) { f*x::atmi::reset_tperrno(); return 0; } if (rc == TX_ERROR || rc == TX_FAIL) { TPERROR(TPERMERR, "tx_commit()=%d", rc); } else if (rc == TX_MIXED) { TPERROR(TPEHEURISTIC, "tx_commit()=%d", rc); } else if (rc == TX_HAZARD) { TPERROR(TPEHAZARD, "tx_commit()=%d", rc); } else if (rc == TX_ROLLBACK) { TPERROR(TPEABORT, "Transaction was rolled back, tx_commit()=%d", rc); } else if (rc == TX_PROTOCOL_ERROR) { TPERROR(TPEPROTO, "tx_commit()=%d", rc); } else { TPERROR(TPESYSTEM, "Unexpected tx_commit()=%d", rc); } return -1; }
static void test_call() { char *r[] = { "one_r1" }; char *w[] = { }; char *t[] = { "___param" }; /* simulate a function call whih ignores the return value of a function see stmt_call for implementation details */ Head *head = env_head(env, "one_r1"); Rel *stmts[] = { rel_store("___param", rel_load(head, "one_r1")), rel_store("___param", rel_load(head, "one_r1")) }; Rel *fn = rel_call(r, 1, w, 0, t, 1, stmts, 2, NULL, 0, NULL, "", NULL); Vars *wvars = vars_new(0); long long sid = tx_enter("", rvars, wvars); vars_free(wvars); load_vars(); rel_eval(fn, vars, &arg); rel_free(fn); rel_free(stmts[0]); rel_free(stmts[1]); free_vars(); tx_commit(sid); }
static int count(const char *name) { Rel *r = load(name); Vars *wvars = vars_new(0); long long sid = tx_enter("", rvars, wvars); load_vars(); rel_eval(r, vars, &arg); Tuple *t; int i = 0; while ((t = tbuf_next(r->body)) != NULL) { tuple_free(t); i++; } rel_free(r); free_vars(); tx_commit(sid); vars_free(wvars); return i; }
/************************************* * 功能: 交易提交 * * 参数: 无 * * 返回值: * * =0 成功 * * <0 失败 * **************************************/ int cslcommit() { int i; #ifdef TX i=tx_commit(); #else i=tpcommit((long)0); #endif /*TX*/ if(i==-1) return(0-TuxedoErrNo[tperrno].ierrno); else return 0; }
int refund(char *username, char *ticketid) { if(!has_user_bought(username, ticketid)) return 1; t_ticket *tkt = find_ticket_by_id(ticketid); if(tkt == NULL) return 1; if(tkt->num == 0) return 1; ++tkt->num; tx_begin(); int rc = update_ticket(tkt->id, tkt); if(rc) { tx_rollback(); return 1; } rc = del_user_ticket(username, ticketid); if(rc) { tx_rollback(); return 1; } tx_commit(); rtss_log("%s refund %s", username, ticketid); return 0; }
static int equal(Rel *left, const char *name) { Rel *right = load(name); Vars *wvars = vars_new(0); long long sid = tx_enter("", rvars, wvars); load_vars(); rel_eval(left, vars, &arg); rel_eval(right, vars, &arg); int res = rel_eq(left, right); rel_free(left); rel_free(right); free_vars(); tx_commit(sid); vars_free(wvars); return res; }
static void test_store() { Rel *r = load("one_r1"); Vars *wvars = vars_new(1); vars_add(wvars, "one_r1_cpy", 0, NULL); long long sid = tx_enter("", rvars, wvars); load_vars(); rel_eval(r, vars, &arg); vol_write(wvars->vols[0], r->body, wvars->names[0], wvars->vers[0]); rel_free(r); free_vars(); tx_commit(sid); vars_free(wvars); if (!equal(load("one_r1"), "one_r1_cpy")) fail(); /* TODO: test reassignment in one statement logic */ }
int main(int argc, char *argv[]) { char *pgm = argv[0]; int rc, commit, test_rc; if (argc < 3) { fprintf(stderr, "%s: at least two options must be specified\n", argv[0]); exit (1); } commit = strtol(argv[1], NULL, 0); test_rc = strtol(argv[2], NULL, 0); printf("%s| starting...\n", pgm); printf("%s| tx_open(): %d\n", pgm, rc = tx_open()); assert(TX_OK == rc); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OK == rc); if (commit) printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); else printf("%s| tx_rollback(): %d\n", pgm, rc = tx_rollback()); assert(test_rc == rc); printf("%s| tx_close(): %d\n", pgm, rc = tx_close()); if (TX_FAIL == test_rc) { assert(TX_FAIL == rc); lixa_tx_close_cleanup(); } else assert(TX_OK == rc); printf("%s| ...finished\n", pgm); return 0; }
static int equal_clone(const char *name) { Rel *cp1 = load(name); Rel *cp2 = load(name); Vars *wvars = vars_new(0); long long sid = tx_enter("", rvars, wvars); load_vars(); rel_eval(cp1, vars, &arg); rel_eval(cp2, vars, &arg); int res = rel_eq(cp1, cp2); rel_free(cp1); rel_free(cp2); free_vars(); tx_commit(sid); vars_free(wvars); return res; }
int main(int argc, char *argv[]) { char *pgm = argv[0]; int rc; long begin_pos; int rmid; if (argc < 2) { fprintf(stderr, "%s: at least one option must be specified\n", argv[0]); exit (1); } begin_pos = strtol(argv[1], NULL, 0); printf("%s| starting...\n", pgm); printf("%s| tx_open(): %d\n", pgm, rc = tx_open()); assert(TX_OK == rc); if (0 == begin_pos) { printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OK == rc); } /* emulate callback registration from resource manager when accessing * resource manager owned resources; you may imagine these are the * equivalent of a SQLExecDirect function call */ for (rmid=0; rmid<3; ++rmid) { printf("%s| lixa_monkeyrm_call_ax_reg(%d): %d\n", pgm, rmid, rc = lixa_monkeyrm_call_ax_reg(rmid)); } if (1 == begin_pos) { printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OUTSIDE == rc); } /* emulate callback de-registration from resource manager when accessing * resource manager owned resources; you may imagine these are the * equivalent of a SQLEndTran function call */ for (rmid=0; rmid<3; ++rmid) { printf("%s| lixa_monkeyrm_call_ax_unreg(%d): %d\n", pgm, rmid, rc = lixa_monkeyrm_call_ax_unreg(rmid)); if (0 == begin_pos) assert(TMER_PROTO == rc); } if (2 == begin_pos) { printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OK == rc); } printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); if (1 == begin_pos) assert(TX_PROTOCOL_ERROR == rc); else assert(TX_OK == rc); /* emulate callback registration from resource manager when accessing * resource manager owned resources; you may imagine these are the * equivalent of a SQLExecDirect function call */ for (rmid=0; rmid<3; ++rmid) { printf("%s| lixa_monkeyrm_call_ax_reg(%d): %d\n", pgm, rmid, rc = lixa_monkeyrm_call_ax_reg(rmid)); assert(TM_OK == rc); } /* emulate callback de-registration from resource manager when accessing * resource manager owned resources; you may imagine these are the * equivalent of a SQLEndTran function call */ for (rmid=0; rmid<3; ++rmid) { printf("%s| lixa_monkeyrm_call_ax_unreg(%d): %d\n", pgm, rmid, rc = lixa_monkeyrm_call_ax_unreg(rmid)); assert(TM_OK == rc); } printf("%s| tx_close(): %d\n", pgm, rc = tx_close()); assert(TX_OK == rc); /* memory leak prevention */ lixa_monkeyrm_call_cleanup(); printf("%s| ...finished\n", pgm); return 0; }
int main(int argc, char *argv[]) { /* generic variables */ int txrc; /* PostgreSQL variables */ PGconn *conn; PGresult *res; /* control variables */ int commit; int insert; int test_rc; if (argc < 4) { fprintf(stderr, "%s: at least two options must be specified\n", argv[0]); exit (1); } commit = strtol(argv[1], NULL, 0); insert = strtol(argv[2], NULL, 0); test_rc = strtol(argv[3], NULL, 0); /* open the resource manager(s) */ if (TX_OK != (txrc = tx_open())) { fprintf(stderr, "tx_open error: %d\n", txrc); exit(txrc); } /* retrieve the connection handler */ conn = lixa_pq_get_conn(); if (NULL == conn) { fprintf(stderr, "lixa_pq_get_conn: conn is NULL\n"); exit(1); } /* trivial check for lixa_pq_is_managed_conn() function */ if (!lixa_pq_is_managed_conn(conn)) { fprintf(stderr, "lixa_pq_is_managed_conn: returned FALSE, this " "should be impossible!\n"); exit(1); } /* start a new transaction */ if (TX_OK != (txrc = tx_begin())) { fprintf(stderr, "tx_begin error: %d\n", txrc); exit(txrc); } /* insert data */ if (insert) { res = PQexec( conn, "INSERT INTO authors VALUES(9, 'Name', 'Surname');"); if (PGRES_COMMAND_OK != PQresultStatus(res)) { fprintf(stderr, "INSERT INTO authors: %s", PQerrorMessage(conn)); PQclear(res); exit_nicely(conn); } PQclear(res); } else { res = PQexec( conn, "DELETE FROM authors;"); if (PGRES_COMMAND_OK != PQresultStatus(res)) { fprintf(stderr, "DELETE FROM authors: %s", PQerrorMessage(conn)); PQclear(res); exit_nicely(conn); } PQclear(res); } /* commit transaction */ if (commit) { if (test_rc != (txrc = tx_commit())) { fprintf(stderr, "tx_commit error: %d instead of %d\n", txrc, test_rc); exit(txrc); } } else { if (test_rc != (txrc = tx_rollback())) { fprintf(stderr, "tx_rollback error: %d instead of %d\n", txrc, test_rc); exit(txrc); } } /* close the resource manager */ if (TX_OK != (txrc = tx_close())) { fprintf(stderr, "tx_close error: %d\n", txrc); exit(txrc); } return 0; }
void main(int argc, char *argv[]) { char val[512], *p; char rbuf[512+1]; char svcname[17]; int timeout; long revent, rcvlen; FLDKEY key; FBUF *transf; FILE *fp; int cd, n, fflag=0, i, idx=0; int ret; /* if (argc != 2) { fprintf(stderr, "Usage:%s input-file\n", argv[0]); exit(1); } */ if(parseArg(argc, argv)<0){ printf("parseArg error!!\n"); exit(1); } if( (fp=fopen(filename, "r")) == (FILE *)0 ){ printf( "file open error [%d:%s]\n", errno, strerror(errno) ); exit( 1 ); } memset( svcname, 0x00, sizeof(svcname) ); if( get_svcname(fp, svcname) < 0 ){ printf( "get_svcname() failed!! -- (input-file=%s)\n", argv[1] ); exit(1); } timeout = 5; n = tpstart((TPSTART_T *)NULL); if (n < 0) { fprintf(stderr, "tpstart fail tperrno = %s\n", tperrno); exit(1); } printf("tpstart ok!\n"); transf = fballoc(100, 100); if( transf == NULL) { fprintf(stderr, "fballoc fail: rcvbuf tperrno = %d\n", tperrno); tpend(); exit(1); } Finit(transf, Fsizeof(transf)); while( 1 ){ memset( rbuf, 0x00, sizeof(rbuf) ); if( fgets(rbuf, sizeof(rbuf)-1, fp)==(char *) 0 ){ break; } p = strchr(rbuf, '\n'); if( p == (char *)0 && strlen(rbuf) >= sizeof(rbuf)-1 ){ printf( "한 라인의 길이가 너무 길어 무시합니다..\n" ); printf( "=>[%s]\n", rbuf ); continue; } *p = 0x00; memset( val, 0x00, sizeof(val) ); key = 0; if( line_proc(rbuf, &key, &idx, val)<0 ) continue; PUT(key, idx, val); printf( "key=%d, idx=%d, val=%s\n", key, idx, val ); fflag = 1; } if( !fflag ){ printf( "not exist send data .....\n" ); fbfree( transf ); tpend(); exit(1); } printf( ">>service[%s], send data->\n", svcname ); fbprint( transf ); printf( "\t----------------------------------------------------\n\n\n" ); fflush( stdout ); /* original cd = tpconnect(svcname, (char *)transf, fbget_fbsize(transf), TPRECVONLY); */ if(flag==1){ ret = tx_begin(); printf("tx_begin() [%s] \n", ret==TX_OK ? "success" : "fail"); if(ret!=TX_OK) exit(1); } cd = tpcall(svcname, (char *)transf, fbget_fbsize(transf), (char **)&transf, (long *)&rcvlen, 0); if (cd < 0) { if(flag==1){ ret = tx_rollback(); printf("tx_rollback() [%s] \n", ret==TX_OK ? "success" : "fail"); if(ret!=TX_OK) exit(1); } fprintf(stderr, "tpcall fail tperrno = %d\n", tperrno); fbfree( transf ); tpend(); exit(1); } fprintf(stdout, "TPCALL SUCCESS!!\n"); if(flag==1){ ret = tx_commit(); printf("tx_commit() [%s] \n", ret==TX_OK ? "success" : "fail"); if(ret!=TX_OK) exit(1); } /* i = 0; while( 1 ){ Finit(transf, Fsizeof(transf)); n = tprecv(cd, (char **)&transf, (long *)&rcvlen, 0, &revent); if (n < 0 && tperrno == TPEEVENT ){ if(revent == TPEV_SVCSUCC ) printf( "service completed(TPSUCC) !\n" ); else if(revent == TPEV_SVCFAIL ) printf( "service completed(TPFAIL) !\n" ); else{ printf( "tprecv error : event[0x%08X], tperrno[%d]\n", revent, tperrno ); break; } } else if( n < 0 ){ printf( "tprecv error(no event) : tperrno[%d]\n", tperrno ); break; } fbprint( transf ); printf( "\t------------------------------------------------------[%3d th]\n\n", i++ ); fflush( stdout ); if (n < 0 ) break; } */ fbfree(transf); tpend(); }
int main(int argc, char *argv[]) { char *pgm = argv[0]; TXINFO info; int rc; printf("%s| starting...\n", pgm); printf("%s| tx_set_commit_return(): %d\n", pgm, rc = tx_set_commit_return(TX_COMMIT_COMPLETED)); assert(TX_PROTOCOL_ERROR == rc); printf("%s| tx_open(): %d\n", pgm, rc = tx_open()); assert(TX_OK == rc); printf("%s| tx_set_commit_return(): %d\n", pgm, rc = tx_set_commit_return(333)); assert(TX_EINVAL == rc); printf("%s| tx_info(): %d\n", pgm, tx_info(&info)); assert(TX_COMMIT_COMPLETED == info.when_return); printf("%s| tx_set_commit_return(): %d\n", pgm, rc = tx_set_commit_return(TX_COMMIT_COMPLETED)); assert(TX_OK == rc); printf("%s| tx_info(): %d\n", pgm, tx_info(&info)); assert(TX_COMMIT_COMPLETED == info.when_return); printf("%s| tx_set_commit_return(): %d\n", pgm, rc = tx_set_commit_return(TX_COMMIT_DECISION_LOGGED)); assert(TX_NOT_SUPPORTED == rc); printf("%s| tx_info(): %d\n", pgm, tx_info(&info)); assert(TX_COMMIT_COMPLETED == info.when_return); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OK == rc); printf("%s| tx_set_commit_return(): %d\n", pgm, rc = tx_set_commit_return(TX_COMMIT_COMPLETED)); assert(TX_OK == rc); printf("%s| tx_info(): %d\n", pgm, tx_info(&info)); assert(TX_COMMIT_COMPLETED == info.when_return); printf("%s| tx_set_commit_return(): %d\n", pgm, rc = tx_set_commit_return(TX_COMMIT_DECISION_LOGGED)); assert(TX_NOT_SUPPORTED == rc); printf("%s| tx_info(): %d\n", pgm, tx_info(&info)); assert(TX_COMMIT_COMPLETED == info.when_return); printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); assert(TX_OK == rc); printf("%s| tx_close(): %d\n", pgm, rc = tx_close()); assert(TX_OK == rc); /* memory leak prevention */ lixa_monkeyrm_call_cleanup(); printf("%s| ...finished\n", pgm); return 0; }
int main(int argc, char *argv[]) { char *pgm = argv[0]; TXINFO info; int rc; long fail_point; if (argc < 2) { fprintf(stderr, "%s: at least one option must be specified\n", argv[0]); exit(1); } fail_point = strtol(argv[1], NULL, 0); printf("%s| starting...\n", pgm); printf("%s| tx_open(): %d\n", pgm, rc = tx_open()); assert(TX_OK == rc); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); if (0 == fail_point) assert(TX_FAIL == rc); else assert(TX_OK == rc); printf("%s| tx_set_transaction_control(): %d\n", pgm, rc = tx_set_transaction_control(TX_UNCHAINED)); if (0 == fail_point) assert(TX_FAIL == rc); else assert(TX_OK == rc); printf("%s| tx_set_commit_return(): %d\n", pgm, rc = tx_set_commit_return(TX_COMMIT_COMPLETED)); if (0 == fail_point) assert(TX_FAIL == rc); else assert(TX_OK == rc); printf("%s| tx_set_transaction_timeout(): %d\n", pgm, rc = tx_set_transaction_timeout(1)); if (0 == fail_point) assert(TX_FAIL == rc); else assert(TX_OK == rc); printf("%s| tx_info(): %d\n", pgm, tx_info(&info)); if (0 == fail_point) assert(TX_FAIL == rc); else assert(TX_OK == rc); if (0 == fail_point) { printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); assert(TX_FAIL == rc); printf("%s| tx_rollback(): %d\n", pgm, rc = tx_rollback()); assert(TX_FAIL == rc); printf("%s| ...finished (TX_FAIL)\n", pgm); /* memory leak prevention */ lixa_monkeyrm_call_cleanup(); return 0; } printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); if (1 == fail_point) assert(TX_FAIL == rc); else assert(TX_OK == rc); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); if (1 == fail_point) { assert(TX_FAIL == rc); printf("%s| ...finished (TX_FAIL)\n", pgm); /* memory leak prevention */ lixa_monkeyrm_call_cleanup(); return 0; } else assert(TX_OK == rc); printf("%s| tx_rollback(): %d\n", pgm, rc = tx_rollback()); if (2 == fail_point) assert(TX_FAIL == rc); else assert(TX_OK == rc); printf("%s| tx_close(): %d\n", pgm, rc = tx_close()); if (2 == fail_point) { assert(TX_FAIL == rc); printf("%s| ...finished (TX_FAIL)\n", pgm); /* memory leak prevention */ lixa_monkeyrm_call_cleanup(); return 0; } else assert(TX_OK == rc); printf("%s| tx_open(): %d\n", pgm, rc = tx_open()); assert(TX_OK == rc); printf("%s| tx_close(): %d\n", pgm, rc = tx_close()); if (3 == fail_point) assert(TX_FAIL == rc); else assert(TX_OK == rc); printf("%s| tx_open(): %d\n", pgm, rc = tx_open()); if (3 == fail_point) { assert(TX_FAIL == rc); printf("%s| ...finished (TX_FAIL)\n", pgm); exit(0); } else assert(TX_OK == rc); printf("%s| ...finished\n", pgm); return 0; }
int main(int argc, char *argv[]) { /* generic variables */ int txrc; /* IBM DB2 variables */ SQLRETURN rc_cli = SQL_SUCCESS; SQLHANDLE env, conn, stat; char db_name[] = "sample"; char user[] = ""; char passwd[] = ""; SQLCHAR sql_stat_i[] = "INSERT INTO DB2INST1.DEPT " "(DEPTNO, DEPTNAME, ADMRDEPT) " "VALUES('Z99', 'RESEARCH & DEVELOPMENT', 'E01')"; SQLCHAR sql_stat_d[] = "DELETE DB2INST1.DEPT WHERE DEPTNO='Z99'"; SQLCHAR *sql_stat = NULL; /* control variables */ int commit; int insert; int test_rc; if (argc < 4) { fprintf(stderr, "%s: at least three options must be specified\n", argv[0]); exit (1); } commit = strtol(argv[1], NULL, 0); insert = strtol(argv[2], NULL, 0); test_rc = strtol(argv[3], NULL, 0); /* open the resource manager(s) */ if (TX_OK != (txrc = tx_open())) { fprintf(stderr, "tx_open error: %d\n", txrc); exit(txrc); } if (SQL_SUCCESS != (rc_cli = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env))) { fprintf(stderr, "Unable to allocate the environment handle: %d\n", rc_cli); exit(1); } if (SQL_SUCCESS != (rc_cli = SQLSetEnvAttr( env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0))) { fprintf(stderr, "Unable to set ODBC version 3.0: %d\n", rc_cli); exit(1); } if (SQL_SUCCESS != (rc_cli = SQLAllocHandle( SQL_HANDLE_DBC, env, &conn))) { fprintf(stderr, "Unable to allocate the connection handle: %d\n", rc_cli); exit(1); } if (SQL_SUCCESS != (rc_cli = SQLSetConnectAttr( conn, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS))) { fprintf(stderr, "Unable to set autocommit (OFF) attribute: %d\n", rc_cli); exit(1); } if (SQL_SUCCESS != (rc_cli = SQLConnect( conn, (SQLCHAR *)db_name, SQL_NTS, (SQLCHAR *)user, SQL_NTS, (SQLCHAR *)passwd, SQL_NTS))) { fprintf(stderr, "Unable to connect to database '%s': %d\n", db_name, rc_cli); exit(1); } if (SQL_SUCCESS != (rc_cli = SQLAllocHandle( SQL_HANDLE_STMT, conn, &stat))) { fprintf(stderr, "Unable to allocate the statement handle: %d\n", rc_cli); exit(1); } if (TX_OK != (txrc = tx_begin())) { fprintf(stderr, "tx_begin error: %d\n", txrc); exit(txrc); } /* insert data */ if (insert) { if (SQL_SUCCESS != (rc_cli = SQLExecDirect( stat, sql_stat_i, SQL_NTS))) { fprintf(stderr, "Unable to execute the SQL statement ('%s'): %d\n", sql_stat_i, rc_cli); exit(1); } } else { if (SQL_SUCCESS != (rc_cli = SQLExecDirect( stat, sql_stat_d, SQL_NTS))) { fprintf(stderr, "Unable to execute the SQL statement ('%s'): %d\n", sql_stat_d, rc_cli); exit(1); } } /* commit transaction */ if (commit) { if (test_rc != (txrc = tx_commit())) { fprintf(stderr, "tx_commit error: %d\n", txrc); exit(txrc); } } else { if (test_rc != (txrc = tx_rollback())) { fprintf(stderr, "tx_rollback error: %d\n", txrc); exit(txrc); } } if (SQL_SUCCESS != (rc_cli = SQLFreeHandle(SQL_HANDLE_STMT, stat))) { fprintf(stderr, "Unable to free the statement handle: %d\n", rc_cli); exit(1); } if (SQL_SUCCESS != (rc_cli = SQLDisconnect(conn))) { fprintf(stderr, "Unable to disconnect from database '%s': %d\n", db_name, rc_cli); exit(1); } if (SQL_SUCCESS != (rc_cli = SQLFreeHandle(SQL_HANDLE_DBC, conn))) { fprintf(stderr, "Unable to free the connection handle: %d\n", rc_cli); exit(1); } if (SQL_SUCCESS != (rc_cli = SQLFreeHandle(SQL_HANDLE_ENV, env))) { fprintf(stderr, "Unable to free the environment handle: %d\n", rc_cli); exit(1); } /* close the resource manager(s) */ if (TX_OK != (txrc = tx_close())) { fprintf(stderr, "tx_close error: %d\n", txrc); exit(txrc); } return 0; }
int main(int argc, char *argv[]) { char *pgm = argv[0]; int rc, test_rc; int rmid = 2; if (argc < 2) { fprintf(stderr, "%s: at least one option must be specified\n", argv[0]); exit (1); } test_rc = strtol(argv[1], NULL, 0); printf("%s| starting...\n", pgm); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_PROTOCOL_ERROR == rc); printf("%s| tx_open(): %d\n", pgm, rc = tx_open()); assert(TX_OK == rc); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OK == rc); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_PROTOCOL_ERROR == rc); printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); assert(TX_OK == rc); printf("%s| lixa_monkeyrm_call_ax_reg(%d): %d\n", pgm, rmid, rc = lixa_monkeyrm_call_ax_reg(rmid)); assert(TM_OK == rc); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OUTSIDE == rc); printf("%s| lixa_monkeyrm_call_ax_unreg(%d): %d\n", pgm, rmid, rc = lixa_monkeyrm_call_ax_unreg(rmid)); assert(TM_OK == rc); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OK == rc); printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); assert(TX_OK == rc); printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(test_rc == rc); if (TX_FAIL == test_rc) { /* test can not go on after TX_FAIL */ /* memory leak prevention */ lixa_monkeyrm_call_cleanup(); printf("%s| ...finished\n", pgm); return 0; } printf("%s| tx_begin(): %d\n", pgm, rc = tx_begin()); assert(TX_OK == rc); printf("%s| lixa_monkeyrm_call_ax_reg(%d): %d\n", pgm, rmid, rc = lixa_monkeyrm_call_ax_reg(rmid)); assert(TM_OK == rc); printf("%s| tx_commit(): %d\n", pgm, rc = tx_commit()); assert(TX_OK == rc); printf("%s| tx_close(): %d\n", pgm, rc = tx_close()); assert(TX_OK == rc); /* memory leak prevention */ lixa_monkeyrm_call_cleanup(); printf("%s| ...finished\n", pgm); return 0; }
static void processor(const char *tx_addr, int port) { sys_init(1); sys_log('E', "started port=%d, tx=%s\n", port, tx_addr); /* connect to the control thread */ char addr[MAX_ADDR]; sys_address(addr, port); IO *io = sys_connect(addr, IO_CHUNK); tx_attach(tx_addr); /* get env code from the tx */ char *code = tx_program(); char *res = mem_alloc(MAX_BLOCK); while (!io->stop) { sys_iready(io, -1); int status = -1; long long sid = 0LL, time = sys_millis(); Env *env = NULL; Arg *arg = NULL; Vars *v = vars_new(0), *r = NULL, *w = NULL; Http_Req *req = http_parse_req(io); if (io->stop) goto exit; if (req == NULL) { status = http_400(io); goto exit; } if (req->method == OPTIONS) { status = http_opts(io); goto exit; } env = env_new("net", code); if (str_idx(req->path, "/fn") == 0) { int idx = (req->path[3] == '/') ? 4 : 3; int i = 0, len = 1, cnt = 0; Func **fns = env_funcs(env, req->path + idx, &cnt); status = http_200(io); while (status == 200 && len) { len = pack_fn2csv(fns, cnt, res, MAX_BLOCK, &i); status = http_chunk(io, res, len); } mem_free(fns); goto exit; } /* compare the request with the function defintion */ Func *fn = env_func(env, req->path + 1); if (fn == NULL) { Error *err = error_new("unknown function '%s'", req->path + 1); status = http_404(io, err->msg); mem_free(err); goto exit; } if (fn->rp.name != NULL && req->method != POST) { status = http_405(io, POST); goto exit; } if (fn->rp.name == NULL && req->method == POST) { status = http_405(io, GET); goto exit; } /* TODO: think what to do with duplicate parameter values */ for (int i = 0; i < req->args->len; ++i) { char *name = req->args->names[i]; if (array_freq(req->args->names, req->args->len, name) > 1) { Error *err = error_new("duplicate parameter '%s' " "(not supported)", name); status = http_404(io, err->msg); mem_free(err); goto exit; } } if (fn->pp.len != req->args->len) { Error *err = error_new("expected %d primitive parameters, got %d", fn->pp.len, req->args->len); status = http_404(io, err->msg); mem_free(err); goto exit; } arg = mem_alloc(sizeof(Arg)); for (int i = 0; i < fn->pp.len; ++i) { char *name = fn->pp.names[i]; Type t = fn->pp.types[i]; int idx = array_scan(req->args->names, req->args->len, name); if (idx < 0) { Error *err = error_new("unknown parameter '%s'", name); status = http_404(io, err->msg); mem_free(err); goto exit; } char *val = req->args->vals[idx]; int error = 0; if (t == Int) { arg->vals[i].v_int = str_int(val, &error); } else if (t == Real) arg->vals[i].v_real = str_real(val, &error); else if (t == Long) arg->vals[i].v_long = str_long(val, &error); else if (t == String) { error = str_len(val) > MAX_STRING; if (!error) str_cpy(arg->vals[i].v_str, val); } if (error) { Error *err = error_new("value '%s' (parameter '%s') " "is not of type '%s'", val, name, type_to_str(t)); status = http_404(io, err->msg); mem_free(err); goto exit; } } if (fn->rp.name != NULL) { TBuf *body = NULL; if (req->len > 0) { Error *err = pack_csv2rel(req->body, fn->rp.head, &body); if (err != NULL) { status = http_404(io, err->msg); mem_free(err); goto exit; } } else { body = tbuf_new(); } vars_add(v, fn->rp.name, 0, body); /* project the parameter */ Rel *param = rel_project(rel_load(fn->rp.head, fn->rp.name), fn->rp.head->names, fn->rp.head->len); rel_eval(param, v, arg); /* clean the previous version */ tbuf_clean(body); tbuf_free(body); /* replace with the new body */ int vpos = array_scan(v->names, v->len, fn->rp.name); v->vals[vpos] = param->body; param->body = NULL; rel_free(param); } /* start a transaction */ r = vars_new(fn->r.len); w = vars_new(fn->w.len); for (int i = 0; i < fn->r.len; ++i) vars_add(r, fn->r.names[i], 0, NULL); for (int i = 0; i < fn->w.len; ++i) vars_add(w, fn->w.names[i], 0, NULL); sid = tx_enter(addr, r, w); /* prepare variables */ for (int i = 0; i < r->len; ++i) { TBuf *body = vol_read(r->vols[i], r->names[i], r->vers[i]); vars_add(v, r->names[i], 0, body); } for (int i = 0; i < w->len; ++i) { int pos = array_scan(v->names, v->len, w->names[i]); if (pos < 0) vars_add(v, w->names[i], 0, NULL); } for (int i = 0; i < fn->t.len; ++i) vars_add(v, fn->t.names[i], 0, NULL); /* evaluate the function body */ for (int i = 0; i < fn->slen; ++i) rel_eval(fn->stmts[i], v, arg); /* prepare the return value. note, the resulting relation is just a container for the body, so it is not freed */ Rel *ret = NULL; if (fn->ret != NULL) ret = fn->stmts[fn->slen - 1]; /* persist the global variables */ for (int i = 0; i < w->len; ++i) { int idx = array_scan(v->names, v->len, w->names[i]); if (idx < 0) { status = http_500(io); goto exit; } vol_write(w->vols[i], v->vals[idx], w->names[i], w->vers[i]); tbuf_free(v->vals[idx]); v->vals[idx] = NULL; } /* confirm a success and send the result back */ status = http_200(io); if (status != 200) goto exit; tx_commit(sid); /* N.B. there is no explicit revert as the transaction manager handles nested tx_enter and a connectivity failure as a rollback */ int len = 1, i = 0; while (status == 200 && len) { len = pack_rel2csv(ret, res, MAX_BLOCK, i++); status = http_chunk(io, res, len); } exit: if (status != -1) sys_log('E', "%016llX method %c, path %s, time %lldms - %3d\n", sid, (req == NULL) ? '?' : req->method, (req == NULL) ? "malformed" : req->path, sys_millis() - time, status); if (r != NULL) vars_free(r); if (w != NULL) vars_free(w); if (arg != NULL) mem_free(arg); if (req != NULL) http_free_req(req); if (env != NULL) env_free(env); for (int i = 0; i < v->len; ++i) if (v->vals[i] != NULL) { tbuf_clean(v->vals[i]); tbuf_free(v->vals[i]); } vars_free(v); sys_term(io); } mem_free(code); mem_free(res); tx_detach(); sys_close(io); }
void *transaction(void *parm) { int rc; TXINFO info; struct timeval to; struct thread_data_s *data = (struct thread_data_s *)parm; printf("%s| tx_open(): %d\n", data->pgm, rc = tx_open()); assert(TX_OK == rc); if (data->rnd) { to.tv_sec = 0; to.tv_usec = random() % data->rnd; printf("%s| waiting %ld us\n", data->pgm, to.tv_usec); select(0, NULL, NULL, NULL, &to); } printf("%s| tx_begin(): %d\n", data->pgm, rc = tx_begin()); assert(TX_OK == rc); if (data->rnd) { to.tv_sec = 0; to.tv_usec = random() % data->rnd; printf("%s| waiting %ld us\n", data->pgm, to.tv_usec); select(0, NULL, NULL, NULL, &to); } printf("%s| tx_info(): %d\n", data->pgm, rc = tx_info(&info)); assert(1 == rc); /* emulate callback registration from resource manager when accessing * resource manager owned resources; you may imagine these are the * equivalent of a SQLExecDirect function call */ if (data->rnd) { to.tv_sec = 0; to.tv_usec = random() % data->rnd; printf("%s| waiting %ld us\n", data->pgm, to.tv_usec); select(0, NULL, NULL, NULL, &to); } lixa_monkeyrm_call_ax_reg(2); if (data->rnd) { to.tv_sec = 0; to.tv_usec = random() % data->rnd; printf("%s| waiting %ld us\n", data->pgm, to.tv_usec); select(0, NULL, NULL, NULL, &to); } lixa_monkeyrm_call_ax_reg(3); if (data->rnd) { to.tv_sec = 0; to.tv_usec = random() % data->rnd; printf("%s| waiting %ld us\n", data->pgm, to.tv_usec); select(0, NULL, NULL, NULL, &to); } if (data->commit) printf("%s| tx_commit(): %d\n", data->pgm, rc = tx_commit()); else printf("%s| tx_rollback(): %d\n", data->pgm, rc = tx_rollback()); assert(data->expected_rc == rc); if (data->rnd) { to.tv_sec = 0; to.tv_usec = random() % data->rnd; printf("%s| waiting %ld us\n", data->pgm, to.tv_usec); select(0, NULL, NULL, NULL, &to); } printf("%s| tx_close(): %d\n", data->pgm, rc = tx_close()); if (TX_FAIL == data->expected_rc) assert(TX_FAIL == rc); else assert(TX_OK == rc); return NULL; }