Rollback not working coldfusion transaction - coldfusion

I'm using cfscript with a transaction, but it keep the record in the database even though I call the rollback. I'm calling the rollback inside the try not the catch because I need to validate it there.
Here is my code:
transaction action="begin"{
try{
rollbackAction = false;
// Insert into CustomerBilling
insertCustomerBilling = new query();
insertCustomerBilling.setDatasource("rent");
insertCustomerBilling.setName("insertCustomerBilling");
insertCustomerBilling.addParam(name="CustomerID", value="#CompanyID#", cfsqltype="cf_sql_integer");
insertCustomerBilling.addParam(name="Cost", value="#Cost#", cfsqltype="cf_sql_decimal");
insertCustomerBilling.addParam(name="BillDate", value="#DateFormat(Now(), 'yyyy/mm/dd')#", cfsqltype="cf_sql_datetime");
insertCustomerBilling.addParam(name="PaidDate", value="#DateFormat(Now(), 'yyyy/mm/dd')#", cfsqltype="cf_sql_datetime");
result = insertCustomerBilling.execute(sql="INSERT INTO CustomerBilling " &
" (CustomerID, Cost, BillDate, Paid, PaidDate, PropertyID, BillTypeID) " &
" VALUES(:CustomerID, :Cost, :BillDate, 0, :PaidDate, 0, 1 )");
GetCCExemption = new query();
GetCCExemption.setDatasource("rent");
GetCCExemption.setName("GetCCExemption");
GetCCExemption.addParam(name="CompanyID", value="#CompanyID#", cfsqltype="cf_sql_integer");
result = GetCCExemption.execute(sql="Select * From Billing_CCExemptions Where CompanyID = :CompanyID");
rs = result.getResult();
if(rs.recordCount <= 0){
// Check if we inserted customer into Stripe_Customer
GetStripeCustomer = new query();
GetStripeCustomer.setDatasource("rent");
GetStripeCustomer.setName("GetStripeCustomer");
GetStripeCustomer.addParam(name="CompanyID", value="#CompanyID#", cfsqltype="cf_sql_integer");
resultSC = GetStripeCustomer.execute(sql="Select * From Stripe_Customer Where CompanyID = :CompanyID");
rsSC = resultSC.getResult();
if(rsSC.recordCount > 0){
// Charge
charge = oStripe.chargeCustomer();
} else{
// Notify us we haven't inserted into Stripe_Customer
mailerService = new mail();
mailerService.setTo('test#test.com');
mailerService.setFrom("support#test.com");
mailerService.setSubject("Error");
mailerService.setType("html");
mailBody = "ERROR";
mailerService.send(body=mailBody);
transaction action="rollback";
rollbackAction = true;
}
}
if(!rollbackAction){
transaction action="commit";
}
} catch(any e){
transaction action="rollback";
}
}
Does anyone know why the rollback isn't working?
Thanks

Change this:
if(!rollbackAction){
transaction action="commit";
}
} catch(any e){
transaction action="rollback";
to this
if(!rollbackAction){
transaction action="commit";
}
else
transaction action="rollback";
Your catch block only executes if the try block experiences a runtime error. Runtime errors mean, "did not execute". They have nothing to do with unwanted results.

Related

Unit Test for Apex Trigger that Concatenates Fields

I am trying to write a test for a before trigger that takes fields from a custom object and concatenates them into a custom Key__c field.
The trigger works in the Sandbox and now I am trying to get it into production. However, whenever I try and do a System.assert/assertEquals after I create a purchase and perform DML, the value of Key__c always returns null. I am aware I can create a flow/process to do this, but I am trying to solve this with code for my own edification. How can I get the fields to concatenate and return properly in the test? (the commented out asserts are what I have tried so far, and have failed when run)
trigger Composite_Key on Purchases__c (before insert, before update) {
if(Trigger.isBefore)
{
for(Purchases__c purchase : trigger.new)
{
String eventName = String.isBlank(purchase.Event_name__c)?'':purchase.Event_name__c+'-';
String section = String.isBlank(purchase.section__c)?'':purchase.section__c+'-';
String row = String.isBlank(purchase.row__c)?'':purchase.row__c+'-';
String seat = String.isBlank(String.valueOf(purchase.seat__c))?'':String.valueOf(purchase.seat__c)+'-';
String numseats = String.isBlank(String.valueOf(purchase.number_of_seats__c))?'':String.valueOf(purchase.number_of_seats__c)+'-';
String adddatetime = String.isBlank(String.valueOf(purchase.add_datetime__c))?'':String.valueOf(purchase.add_datetime__c);
purchase.Key__c = eventName + section + row + seat + numseats + adddatetime;
}
}
}
#isTest
public class CompositeKeyTest {
public static testMethod void testPurchase() {
//create a purchase to fire the trigger
Purchases__c purchase = new Purchases__c(Event_name__c = 'test', section__c='test',row__c='test', seat__c=1.0,number_of_seats__c='test',add_datetime__c='test');
Insert purchase;
//System.assert(purchases__c.Key__c.getDescribe().getName() == 'testesttest1testtest');
//System.assertEquals('testtesttest1.0testtest',purchase.Key__c);
}
static testMethod void testbulkPurchase(){
List<Purchases__c> purchaseList = new List<Purchases__c>();
for(integer i=0 ; i < 10; i++)
{
Purchases__c purchaserec = new Purchases__c(Event_name__c = 'test', section__c='test',row__c='test', seat__c= i+1.0 ,number_of_seats__c='test',add_datetime__c='test');
purchaseList.add(purchaserec);
}
insert purchaseList;
//System.assertEquals('testtesttest5testtest',purchaseList[4].Key__c,'Key is not Valid');
}
}
You need to requery the records after inserting them to get the updated data from the triggers/database

How to check if mysql query was successful using C++

I'm using a C++ interpreter (ROOT, the CERN framework) to access several mySQL tables in a loop. Every time I query a table that doesn't exist, the program quits on me:
for (int run = 19000; run < 22000; run ++) {
s << run;
num = s.str();
schema = "run_0"+num+"_R007";
s.str("");
//creating our query
query = "select distinct *whatever* from "+schema+".kTrack;";
res = conPtr->Query(query);
conPtr->Close();
//Here is where I don't know what to do:
if (*success*) {
do stuff
}
else {
do stuff
}
}
I don't have a problem if the table returns 0 rows, I have a problem if the table doesn't exist.
What is wrong with my code?
Assuming conPtr is a pointer to a TMySQLServer object, ROOT's documentation for TMySQLServer::Query() says:
Returns a pointer to a TSQLResult object if successful, 0 otherwise. The result object must be deleted by the user.
So Query() returns a NULL pointer on failure.
Also, since your loop is not re-opening a new DB connection on each iteration, you should not be calling conPtr->Close() until after you are done performing queries with it.
Try something more like this:
for (int run = 19000; run < 22000; run ++) {
s << run;
num = s.str();
schema = "run_0"+num+"_R007";
s.str("");
//creating our query
query = "select distinct *whatever* from "+schema+".kTrack;";
res = conPtr->Query(query);
if (res) {
// use res as needed...
delete res;
}
else {
// ...
}
}
conPtr->Close();

How to delete all the items from all tables of Amazon's dynamo db?

Just like backing up all the tables of dynamo db, i also want clear all the tables of my test environment after testing without deleting tables.
We used backup service such a way that we don't want schema structure or java object of table schema as below:
Map<String, AttributeValue> exclusiveStartKey = null;
do {
// Let the rate limiter wait until our desired throughput "recharges"
rateLimiter.acquire(permitsToConsume);
ScanSpec scanSpec = new ScanSpec().withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
.withMaxResultSize(25);
if(exclusiveStartKey!=null){
KeyAttribute haskKey = getExclusiveStartHashKey(exclusiveStartKey, keySchema);
KeyAttribute rangeKey = getExclusiveStartRangeKey(exclusiveStartKey, keySchema);
if(rangeKey!=null){
scanSpec.withExclusiveStartKey(haskKey, rangeKey);
}else{
scanSpec.withExclusiveStartKey(haskKey);
}
}
Table table = dynamoDBInstance.getTable(tableName);
ItemCollection<ScanOutcome> response = table.scan(scanSpec);
StringBuffer data = new StringBuffer();
Iterator<Item> iterator = response.iterator();
while (iterator.hasNext()) {
Item item = iterator.next();
data.append(item.toJSON());
data.append("\n");
}
logger.debug("Data read from table: {} ", data.toString());
if(response.getLastLowLevelResult()!=null){
exclusiveStartKey = response.getLastLowLevelResult().getScanResult().getLastEvaluatedKey();
}else{
exclusiveStartKey = null;
}
// Account for the rest of the throughput we consumed,
// now that we know how much that scan request cost
if(response.getTotalConsumedCapacity()!=null){
double consumedCapacity = response.getTotalConsumedCapacity().getCapacityUnits();
if(logger.isDebugEnabled()){
logger.debug("Consumed capacity : " + consumedCapacity);
}
permitsToConsume = (int)(consumedCapacity - 1.0);
if(permitsToConsume <= 0) {
permitsToConsume = 1;
}
}
} while (exclusiveStartKey != null);
is it possible to delete all items without knowing table schema? can we do it using DeleteItemSpec

NetSuite - error closing return authorization using web services

Within NetSuite when trying to close out Return Authorization line items i receive the following error message:
INSUFFICIENT_PERMISSION
"You do not have permissions to set a value for element item.quantityreceived due to one of the following reasons: 1) The field is read-only; 2) An associated feature is disabled; 3) The field is available either when a record is created or updated, but not in both cases."
Here is the code:
//Pull down the RA in order to work with the line items in question
RecordRef rec = new RecordRef();
rec.internalId = internalId;
rec.type = RecordType.returnAuthorization;
rec.typeSpecified = true;
ReadResponse response = _service.get(rec);
//create the object from the response record returned
ReturnAuthorization ra = (ReturnAuthorization)response.record;
//cancel the order by updating the qty of each item to zero.
WriteResponse res = null;
ReturnAuthorizationItem[] raItemList = ra.itemList.item;
for (int lineCounter = 0; lineCounter < raItemList.Length; lineCounter++)
{
//only if the qty received is zero are we closing out the item(setting qty to zero)
if (raItemList[lineCounter].quantityReceived == 0)
{
raItemList[lineCounter].quantity = 0;
raItemList[lineCounter].quantitySpecified = true;
}
}
//create a new object and add all the changes in order to update the order lines
ReturnAuthorization updRa = new ReturnAuthorization();
updRa.internalId = internalId;
updRa.itemList = new ReturnAuthorizationItemList();
updRa.itemList.item = new ReturnAuthorizationItem[raItemList.Length];
updRa.itemList.item = raItemList;
res = _service.update(updRa);
I am trying to update the line quantity to zero, which in affect will close the Return Authorization if everything has been zeroed out. Question is how do i correct this permissions issue in order to run this update. I have tried setting other fields on this same call. No matter which field i try and update i get the same error message. This is running under an admin account and all permissions look fine as far as i can see. In fact i am running this very same logic against the SaleOrder object to close out Sales Orders with no issues.
Any help would be much appreciated.
Thanks,
Billy
You can't directly edit that line item field. That field is maintained by Netsuite and reflects Item Receipts received against the RA.
If you want to close the RA without receiving just set the line item column field "Closed" to true.
After looking at this a little closer here is the solution:
Replace the if statement in the loop with this:
//only if the qty received and returned are zero do we close out the item(setting qty to zero)
if (raItemList[lineCounter].quantityReceived == 0 && raItemList[lineCounter].quantityBilled == 0)
{
raItemList[lineCounter].quantity = 0;
raItemList[lineCounter].quantitySpecified = true;
raItemList[lineCounter].isClosed = true;
raItemList[lineCounter].isClosedSpecified = true;
raItemList[lineCounter].quantityReceivedSpecified = false;
raItemList[lineCounter].quantityBilledSpecified = false;
raItemList[lineCounter].costEstimateSpecified = false;
}
else
{
raItemList[lineCounter].quantityReceivedSpecified = false;
raItemList[lineCounter].quantityBilledSpecified = false;
raItemList[lineCounter].costEstimateSpecified = false;
}
I am guessing that the fields i had to specific as false are fields that cannot be edited, hence the need to disclude them from the update.
This is a better sample. Note the comment re orderline
/Pull down the RA in order to work with the line items in question
RecordRef rec = new RecordRef();
rec.internalId = internalId;
rec.type = RecordType.returnAuthorization;
rec.typeSpecified = true;
ReadResponse response = _service.get(rec);
//create the object from the response record returned
ReturnAuthorization ra = (ReturnAuthorization)response.record;
//cancel the order by updating the qty of each item to zero.
WriteResponse res = null;
ReturnAuthorizationItem[] raItemList = ra.itemList.item;
ReturnAuthorization updRa = new ReturnAuthorization();
updRa.internalId = internalId;
updRa.itemList = new ReturnAuthorizationItemList();
ReturnAuthorizationItem[] updateItems = new ReturnAuthorizationItem[raItemList.Length];
for (int lineCounter = 0; lineCounter < raItemList.Length; lineCounter++)
{
updateItems[lineCounter].line = raItemList[lineCounter].line; // you'll need to test this. Setting only the line should result in no changes to the RA line items that are not to be closed. use the &xml=T view before and after to make sure orderline (hidden) is still populated properly.
//only if the qty received is zero are we closing out the item(setting qty to zero)
if (raItemList[lineCounter].quantityReceived == 0)
{
updateItems[lineCounter].isClosed = true;
// raItemList[lineCounter].quantitySpecified = true; // is quantitySpecified a field? it wasn't as of the 2012.2 endpoint
}
}
//create a new object and add all the changes in order to update the order lines
updRa.itemList.item = updateItems;
res = _service.update(updRa);

subsonic 3.0 active record update

I am able to retrieve database values and insert database values, but I can't figure out what the Update() syntax should be with a where statement.
Environment -> ASP.Net, C#
Settings.ttinclude
const string Namespace = "subsonic_db.Data";
const string ConnectionStringName = "subsonic_dbConnectionString";
//This is the name of your database and is used in naming
//the repository. By default we set it to the connection string name
const string DatabaseName = "subsonic_db";
Retreive example
var product = equipment.SingleOrDefault(x => x.id == 1);
Insert Example
equipment my_equipment = new equipment();
try
{
// insert
my_equipment.parent_id = 0;
my_equipment.primary_id = 0;
my_equipment.product_code = product_code.Text;
my_equipment.product_description = product_description.Text;
my_equipment.product_type_id = Convert.ToInt32(product_type_id.SelectedItem.Value);
my_equipment.created_date = DateTime.Now;
my_equipment.serial_number = serial_number.Text;
my_equipment.Save();
}
catch (Exception err)
{
lblError.Text = err.Message;
}
Edit: Think that I was just too tired last night, it is pretty easy to update. Just use the retrieve function and use the Update() on that.
var equip = Equipment.SingleOrDefault(x => x.id == 1);
lblGeneral.Text = equip.product_description;
equip.product_description = "Test";
equip.Update();
Resolved. View answer above.